找出数组里出现次数超过一半的数字

这是一个我刚刚毕业时候面试腾讯的面试题,当时我的答案是先排序,然后取中间的数,那么该数就是我们需要的数,但是,这种方法的复杂度不是线性的,所以说就被out了。从那之后,我一直在思考这个问题该如何被线性解决。慢慢地有一个想法,就是制作表,表的大小就是L* 2 (L是数组的长度)。表的每一行第一个元素是数组中的数字,第二个元素是该数字出现的次数。但是,接着想下去,就发现其实在loop数组的同时,我们需要loop该表,因为当我们loop到数组某一元素时,我们要找到表中该数字的出现的次数,然后加一。于是,复杂度一下子就上去了,然后一直被block住。然后竟然没有百度,罪过呀 ^.^ ^.^ ^.^

前几天和一个朋友吃饭聊到这个题目,他说可以根据“出现次数超过一半”这个特性去解题。如果我们同时移除两个不同的数,那么剩下的数中,该数在剩下的数中出现的次数也是超过一半。 这样的话,我们可以按照这个思路做下去,唯一的问题是,如果一个数连续出现很多次,我们该如何去做移除两个不同的数这个动作。 我们可以用一个count来记录,如果出现多次,我们就把它加1,不同的数就减一。代码如下:

#include <stdio.h>
int half_search(int *inPtr, int len);
int half_search(int *inPtr, int len){
  if (inPtr == NULL && len <= 0)
   return -1;
 
  int i, result;
  int count = 0;
  for (i=0;i<len;i++){
      if (count==0){
         result = inPtr[i];
  count = 1;
      }else{
         if(result == inPtr[i])
     count++;
  else
     count--;    
      }
  }
  return result;
}

int main(){
  int a[10] = {1,4,2,5,4,3,4,4,2,4};
  int target_data;
 
  target_data = half_search(a,10); 
  printf("target half mid data: %d. \n",target_data);
 
  return 0;
}
 
 
当然,上面的做法可以网上搜索到,另外,看到网上用哈希表可以解决我之前想用制作表的方法的困境。
 
 
 
 

猜你喜欢

转载自www.cnblogs.com/biggerjun2015/p/9750024.html