【剑指offer】68.数组中出现次数超过一半的数字
总目录:
1.问题描述
给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
数据范围:n≤50000,数组中元素的值 0≤val≤10000
要求:空间复杂度:O(1),时间复杂度 O(n)。
保证数组输入非空,且保证有解
2.问题分析
1哈希
因为需要快速查询某元素出现的次数,所以用哈希,需要2次遍历,1次是填充哈希表,1次是找出现次数最大值。
2排序取中间
因为元素数量超过了一般,则排序之后中间元素必然是目标值
3候选法
选某元素作为候选人且计数器+1,与后面的元素展开PK。
如果相同则计数器+1,如果不同则计数器-1,当计数器清零时换一个候选人。
因为目标值超过一般足以PK掉其他候选人,因此最后剩下的候选人即目标值。
3.代码实例
哈希法
1 class Solution { 2 public: 3 int MoreThanHalfNum_Solution(vector<int> numbers) { 4 unordered_map<int,int> mp; 5 for (const int val : numbers) mp[val]++; 6 for (const int val : numbers) { 7 if (mp[val] > numbers.size() / 2 ) return val; 8 } 9 return 0; 10 } 11 };
排序取中
1 class Solution { 2 public: 3 int MoreThanHalfNum_Solution(vector<int> numbers) { 4 sort(numbers.begin(), numbers.end()); 5 return numbers[numbers.size() / 2]; 6 } 7 };
候选法
class Solution { public: int MoreThanHalfNum_Solution(vector<int> numbers) { int cond = -1; int cnt = 0; for (int i = 0; i < numbers.size(); ++i) { if (cnt == 0) { cond = numbers[i];//更换候选人 cnt = 1; //置信度重置 } else { if (cond == numbers[i]) { cnt++;//置信度+1 } else { cnt--;//置信度-1 } } } return cond; } };
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号