题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路
总述:
若已知给定为指针,则需判断是否为nullptr;另外数组出现次数最多的数字可能并未达到数组长度的一半,需最后判断(checkMoreThanHalf函数)
代码可有两种思路:
1.基于Partition函数(快排关键函数),但会修改输入的数组,如面试官不允许则不能使用此方法
2.(代码使用,首选,不修改输入的数组)遍历数组时保存2个值(数组中的数字,出现的次数times)
遍历至下一个数字时:
如数字相同,times++;
如数字相异,times–;
如次数times=0时,保存下一个数字,且将times=1,继续遍历.
最后判断数组中出现次数最多的数字是否大于数组长度的一半(checkMoreThanHalf函数)
注意:
1.vector的size()函数返回类型为size_type,如需在循环中用到数组长度,则需前面int length = vector.size(),方可比较
代码
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
//判断有效性
if(numbers.empty())
return 0;
//初始化数字 和 次数
int result = numbers[0];
int times = 1;
int length = numbers.size();
//逐个遍历所有数字,找到出现频率最高的数字result
for(int i = 1; i < length; ++i)
{
//次数为0,保存下一个数字,并统计次数
if(times == 0)
{
times = 1;
result = numbers[i];
}
//找到相同数字,次数++
else if(numbers[i] == result)
times++;
//数字相异,次数--
else
times--;
}
//判断出现频率最高的数字result的出现次数是否超过数组的一半
if(!checkMoreThanHalf(numbers, result, length))
return 0;
return result;
}
private:
bool checkMoreThanHalf(vector<int> numbers, int result, int length)
{
//设定是否超过一半的标识
bool isMoreThanHalf = false;
//设定指定数字出现的次数
int resultTimes = 0;
//遍历数组统计result出现次数
for(int i = 0; i < length ; ++i)
{
if(numbers[i] == result)
resultTimes++;
}
if(resultTimes * 2 > length)
isMoreThanHalf = true;
return isMoreThanHalf;
}
};