描述
给定一个长度为n的数组,数组中有一个数组出现的次数超过数组长度的一般,找出这个数字.
例:
输入:[1,2,3,2,2,2,5,4,2]
返回值:2
要求:空间O(1),时间O(N)
解题思路
1.哈希法
先遍历一遍数组,在map中存每个元素出现的次数,再遍历一次数组,找出众数
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int size=numbers.size();
if(size==0) return 0;
unordered_map<int,int> map;
for(auto &val: numbers){
++map[val];
}
for(auto &val: numbers){
if(map[val]>size/2) return val;
}
return 0;
}
};
时间复杂度:O(n)
空间复杂度: O(n)
2.排序法
可以先将数组排序,因为这个数字出现的次数超过数组长度的一般,所以可能的众数肯定在数组中间,然后判断一下。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.empty()) return 0;
sort(numbers.begin(),numbers.end());
int cond=numbers[numbers.size()/2];
return cond;
}
};
时间复杂度:O(nlogn)
空间复杂度: O(1)
3.候选法(最优解)
初始化:候选人cond, 候选人投票次数cnt=0
遍历数组:如果cnt=0,表示没有候选人,则选取当前数为候选人,++cnt
否则:选择一个候选人,如果他后面的数和他相等,曾cnt++,如果不相等,则cnt–
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.empty()) return 0;
int cond=-1,cnt=0;
for(int i=0;i<numbers.size();i++){
if(cnt==0){
cond=numbers[i];
cnt++;
}else{
if(cond==numbers[i]) cnt++;
else cnt--;
}
}
return cond;
}
};
时间复杂度:O(n)
空间复杂度: O(1)