题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:
法1: O(nlogn) 先排序,找到中位数,然后遍历一边确认是否满足要求。
法2: O(n) 注意到目标数 超过数组长度的一半,对数组同时去掉两个不同的数字,到最后剩下的一个数就是该数字。如果剩下两个,那么这两个也是一样的,就是结果),在其基础上把最后剩下的一个数字或者两个回到原来数组中,将数组遍历一遍统计一下数字出现次数进行最终判断。
C++ 法1:
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> number) {
sort(number.begin(), number.end()); //排序,大到小或小到大均可
int key = number[number.size()/2]; //找中位数
int cnt = 0; //统计中位数出现的个数
for(int i=0; i<number.size(); ++i)
if(number[i]==key) ++cnt;
if(cnt>number.size()/2) return key;
else return 0;
}
};
C++ 法2:
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int n = numbers.size();
if (n == 0) return 0;
int num = numbers[0], count = 1;
for (int i = 1; i < n; i++) {
if (numbers[i] == num) count++;
else count--;
if (count == 0) { //如果记数变量为0,那么以下一个数作为当前的被记数变量统计的数
num = numbers[i];
count = 1;
}
}
// Verifying
count = 0;
for (int i = 0; i < n; i++) {
if (numbers[i] == num) count++;
}
if (count * 2 > n) return num;
return 0;
}
};