面试题 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了。

书上代码略

 

posted on 2014-01-26 06:14  Felix Fang  阅读(192)  评论(0)    收藏  举报

导航