题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解题思路:
看到这到题第一时间有两个思路,第一个思路是进行排序,那么如果一定存在这样的一个数的话,最中间的数即为所求!但是排序的复杂度为O(nlogn),有点慢。
第二个思路就是对元素计数,相当于借助哈希表。这样一来时间复杂度为O(N),空间复杂度也为O(N)
int MoreThanHalfNum_Solution(vector<int> numbers) {
unordered_map<int,int> m; //Hash表
int len = numbers.size();
for(int i=0;i<len;i++)
m[numbers[i]]++;
for(auto &it:m)
if(it.second>len/2)
return it.first;
return 0;
}
第三种方法比较巧妙,在不借助额外空间的情况下,时间复杂度也为O(N):
int MoreThanHalfNum_Solution(vector<int> numbers) {
int len = numbers.size();
int times = 1;
int res = numbers.front(); //记res为主元元素
for(int i=0;i<len;i++)
{
if(times==0)
{
res = numbers[i]; //选取新的数字作为主元元素
times = 1;
}
else
{
if(res==numbers[i]) //相等则+1
times++;
else //否则-1
times--;
}
}
times = 0;
for(auto &n:numbers)
if(n==res)
times++; //重新记录主元元素的个数
if(times>len/2) //如果符合要求,则找到了主元元素
return res;
return 0;
}