先排序,再遍历,前后均不相同则计数加1
排序得比较多少次啊。。。,效率太低了吧
@行在途中: 排序很快的
如果是使用HashSet<int>保存的话,每一个数字都要从中寻找,效率更低
你是要结果还是要过程?
意思就是现在有一个三亿个整型数组,要你编程求出这个数组中没有重复出现的数字的个数。
@行在途中:
你要结果就将数据放在数据库里面很快就会有结果,如果你要过程那就……
Dictionary<int, int> dic = new Dictionary<int,int>(300000000);
for(int i=0; i<arr.Length;i++)
{
int count = dic[arr[i]];
count++;
dic[arr[i]]=count;
}
int norepeatCount = 0;//不重复的数字数量
foreach(var item in dic)
{
if(dic[item]==1)
{
norepeatCount++;
}
}
return norepeatCount;
时间复杂度为O(n),空间复杂度为O(n)
呵呵,其实这是腾讯的一道面试题,我当时的回答就是用的这种方法,但是那个面试官说:“你再想想,没有更好的办法了吗?”,我没想出来,所以来网上问问有没有更好的思路。
比如说说像【约瑟夫环】,当我只要求出最后一个出圈的编号时,就只要写下面的代码就可以了
(来源:http://www.cnblogs.com/EricYang/archive/2009/09/04/1560478.html)
@行在途中:
可以用优先队列来实现
还在迷糊啊,答案就在那里,排序的确会比较很多次,而且int类型比较速度也很快
如果是遇到不存在的就存储起来,看起来比较次数是少了,但是索引器里面是要查找的,不管是Dictionary还是Hashset本质都是一样的,当样本非常大的时候占用的资源也是可观的
既然对答案有疑惑,那就自己动手随机生成3亿个数字试试每种方法吧,反正也不费劲,排序速度可是有着绝对优势呢
这么大的数据使用哈希表,需要很大的表空间,才能减少地址冲突,但冲突的数量还是很可观的。
我觉得这问题可以用二叉平衡搜索树来解决,如AVL树或者红黑树。
一个结点的结构可以如下:
public class AVLNode
{
public Key key;
public T value;
public sbyte balance;
public AVLNode left;
public AVLNode right;
}
一个结点大概136b,
最多3亿个节点408 0000 0000 b 约等于38M,
也就是说空间上大概40M;
而AVL插入一个元素(插入时便已经排序)的时间复杂度为O(logn),
总的时间复杂度为O(nlogn),
3亿个节点,所以计算的次数大概为3亿乘以一个不大的常数(log3 0000 0000大概为10)。
这个空间,和时间都可以接受。
==》得解:)
忘了加上解所获得的方式:
分别把3亿个数字加人AVLTree中(红黑树也可),相同数的不会加进去(这是AVLTree的内置机制),加完后AVL的节点数便是解。
提示:二叉平衡搜索树在C++的STL和java的集合库中有已经实现好的类,.Net据我所知还没有官方的实现:( 自己看着办吧
3亿才38M?开啥玩笑啊。
@rockZ:
当时算错了,单位应该是G,38G
表示怀疑,不可以用sql语句来么?