【LeetCode & 剑指offer刷题】数组题7:39 数组中出现次数超过一半的数字
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
39 数组中出现次数超过一半的数字
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
#include <unordered_map> //用hash表实现
using namespace std;
//方法一:hash表实现,O(n),O(n)
class Solution
{
public:
int MoreThanHalfNum_Solution(vector<int> numbers)
{
unordered_map<int,int> counter;
int k = numbers.size() / 2;
for(int ai:numbers) //遍历数组 O(n)
{
counter[ai]++; //构建计数器
if(counter[ai] > k) return ai; //节省时间
}
// for(auto& n:counter) //遍历计数器 O(k) ,这里为map中的引用,不是指针,故直接用n.first
// {
// if(n.second > k)
// {
// return n.first;
// }
// }
return 0; //不存在
}
};
/*
方法二:“消解法”:如果一个数出现次数超过数组的一半,则其出现的次数比其他所有数字出现次数的和还要多,可以用两不同数之间进行消解,最后剩下的数即为出现次数最多那个数
缺点:需要判断是否真的次数超过一半,因为上述条件是必要条件但不是充分条件,时间效率没有hash表法好
O(n),O(1)
例:
1 2 2 2 3
i=0,t=0,res =1,t=1
i=1,不等,t-1=0
i=2,res =a[2] =2,t=1
i=3,相等,t+1=2
i=4,不等,t-1=1
*/
class Solution
{
public:
int MoreThanHalfNum_Solution(vector<int> numbers)
{
int result = numbers[0];
int times = 1;
for(int i = 1;i<numbers.size(); i++)
{
if(times == 0) //候选数,
{
result = numbers[i];
times = 1;
}
else if (numbers[i] == result) times++;//相等时次数加一,
else times--;//不等时减一
}
times = 0;
for(int ai:numbers)//判断是否真的次数超过一半
{
if(ai == result) times++;
}
if(times > numbers.size()/2) return result;
else return 0; //不存在
}
};