题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
这道题和leetcode上第169道题类似,那道题是要求众数,并且众数是一定存在的。但是这道题众数可能不存在,所以这道题仍然可以用那道题的两种解法,只不过在最后要检验一下最后的结果是不是所给数组的众数。
解法一:摩尔投票法 Moore Voting
思路:我们在遍历数组的时候保存两个值,一个为数组中的一个数,一个为计数器。当下一个数字和之前保存的数字相同时,计数器加一,不同时,见一。当计数器为0时,保存当前遍历到的数字,并且计数器加一。如果存在众数的话,那么遍历完数组,最后保存的数就是众数。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0) return 0;
int count =0;
int ans =0;
for(int num:numbers)
{
if(count==0)
{
ans =num;
++count;
}
else
{
(num==ans)?++count:--count;
}
}
if(helper(numbers,ans))
return ans;
else
return 0;
}
bool helper(vector<int> numbers,int val)
{
int times=0;
for(int num:numbers)
{
if(num==val) times++;
}
if(times*2<=numbers.size())
return false;
return true;
}
};
解法二:位操作
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0) return 0;
int ans =0;
for(int i=0;i<32;++i)
{
int ones=0,zeros=0;
for(int num:numbers)
{
if(ones>numbers.size()/2||zeros>numbers.size()/2) break;
if((num &(1<<i))!=0) ++ones;
else ++zeros;
}
if(ones>zeros) ans|=(1<<i);
}
if(helper(numbers,ans))
return ans;
else
return 0;
}
bool helper(vector<int> numbers,int val)
{
int times=0;
for(int num:numbers)
{
if(num==val) times++;
}
if(times*2<=numbers.size())
return false;
return true;
}
};
python 的解法:
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if len(numbers) == 0:
return 0
ans = 0
count =0
for num in numbers:
if count == 0:
ans = num
count += 1
else:
if ans == num:
count += 1
else:
count -= 1
if self.helper(numbers,ans) == True:
return ans
else:
return 0
def helper(self,numbers,val):
times = 0
for num in numbers:
if val == num:
times += 1
if times >(len(numbers)/2):
return True
else:
return False