【算法习作】已知有一个数字在某数组中出现次数超过一半,求这个数
作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/
要求O(n)时间复杂度。
利用“已经知道这个数字在整个数组中出现的比例超过50%”这个事实,采用计数法。
设置两个变量:number表示在遍历过程中出现次数最多的数,flag表示在遍历过程中该数字出现的次数与其他数字出现次数之差。初始化flag为0。
从头遍历数组,首先判断flag是不是为0,如果为0,则number记为当前遍历的数,并且flag++,继续向下遍历(此处需要说明的是,flag为0表示现在尚没有找到某个数次数比别人都多的)
若flag不等于0,那么说明前边有一个数number可能是最后答案,此时将该number与遍历位置上的数字进行比较,相等flag++,不等flag—。
这样遍历完最后得到的number即为所求,此时flag表示出现超过一半的这个数比其余数字多的次数,利用这个数字也可以得到这个出现次数超过一半的数究竟出现了几次,即(SIZE+flag)/2。
实现如下:
1: /*
2: * =====================================================================================3: *4: * Filename: exceedhalf.cpp5: *6: * Description: Find out which number exceeds the half of a array7: *8: * Version: 1.09: * Created: 04/22/2011 08:32:24 AM10: * Revision: none11: * Compiler: g++12: *13: * Author: gnuhpc (http://blog.csdn.net/gnuhpc), warmbupt@gmail.com14: *15: * =====================================================================================16: */17:18: #include <iostream>19: #include "../include/utils.h"
20:21: #define NUMBER 1022: using namespace std;23:24: void findOutHalf(const int* array);25:26: int main(int argc, char *argv[])27: {28: int *array = new int[NUMBER];29: int i =0;
30: while(i<NUMBER){
31: cin >> array[i++];32: }33: findOutHalf(array);34: return 0;
35: }36:37: void findOutHalf(const int* array){38: cout << "===========" <<endl;
39: int number;
40: int flag = 0;
41: for( int i = 0 ; i<NUMBER ; ++i )42: {43: if( flag == 0 )
44: {45: number = array[i];46: ++flag;47: continue;
48: }49:50: ( number == array[i])?(++flag):(--flag);51: }52: cout << number << endl;53: cout << flag << endl;54: }55: