面试题 29,数组中出现次数超过一半的数字

这道题我的第一反映是采用Map<int, int>来做,遇到数字a就map[a]+1,然后判断map[a]是否已经超过数组长度一半了,超过了就输出。
时间复杂度O(n),可惜的是占用了额外的空间。
实际上我忽略了一点:数组中最多只能有一个这样的数字,也就是说要么没有出现次数超过一半的数字,要么只有一个。
答案非常好地利用了这个特点:
定义一个int temp,再定义一个int count。
边界情况:数组为空。
int temp = array[0];
int count = 0;
foreach element in array{
if(temp != element){
count --;
if(count < 0){
temp = element;
count = 0;
}
}else{
count++;
}
}
if(count > 0)
print temp;
遇到相同的数字,count会+1,遇到不同过的数字,count会-1,如果count减到0以下了,temp会被替换成当前数字。
如果存在满足要求的数字,遍历完成后,必然count > 0,而且temp里的值就是那个数字。
这样时间复杂度是O(n),而且空间上不需要定义额外的map了。
书上代码略
------------------------------------------------
Felix原创,转载请注明出处,感谢博客园!
posted on 2014-01-26 06:14 Felix Fang 阅读(192) 评论(0) 收藏 举报
浙公网安备 33010602011771号