数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
分析
语言太枯燥,太绕,直接上图吧
主要两个过程:
- 找到出现次数最多的数
- 验证是否出现次数超过一半
走到这里还不能直接下定论,出现次数多的不一定超过一半,且不一定数组遍历完之后就等于出现次数最多的就是tmp,所以需要验证,将count=0,再遍历一遍数组,将每一个元素与当前tmp比较。如果count大于数组长度的一半,那么tmp就是超过数组长度一半的数字,否则,这个数字不存在。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0)
{
return 0;
}
int count = 1;
int tmp = numbers[0];
int len=numbers.size();
for (int i = 1; i<len; ++i)
{
if (numbers[i] == tmp)
{
count++;
}
else{
count--;
}
if (count == 0)
{
tmp = numbers[i];//因为是出现次数大于n/2的,所以到最后一定会传值到tmp中
count++;
}
}
count=0;
for(int i=0;i<len;i++)
{
if(numbers[i]==tmp)
count++;
}
if(count>(len/2))
{
return tmp;
}
return 0;
}
};
第二种解法
分析
将数组排序,如果存在一个数出现次数超过数组一半,不管这个数在最左,还是最右,它一定在数组中间数的位置,取中间数作为标准值,遍历数组统计个数,超过数组长度一半,即返回中间值,否则就返回0。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int len=numbers.size();
int mid = len>>1;
sort(numbers.begin(),numbers.end());
int tmp=numbers[mid];
int count=0;
for(int i=0;i<len;i++)
{
if(numbers[i]==tmp)
{
count++;
}
}
if(count>(len/2))
{
return tmp;
}
return 0;
}
};
题目来源:https://www.nowcoder.com/questionTerminal/e8a1b01a2df14cb2b228b30ee6a92163