如何在O(n)的时间复杂度内找出数组中出现次数超过了一半的数
方法一:hash法
首先创建一个hash_map,其中,key为数组元素值,value为此数出现的次数。遍历一遍数组,用hash_map统计每个数出现的次数,并用两个值存储目前出现次数最多的数和对应的次数,此时的时间复杂度为O(n),空间复杂度为O(n)
方法二
如果每次删除两个不同的数,那么在剩余的数字里,原出现次数最多的数出现的频率一样超过了50%,不断重复这个过程,最后剩下的将全是同样的数字。具体实现为:
使用两个变量A和B,其中变量A存储某个数组中的数,变量B用来计数。开始时将变量B初始化为0,遍历数组。
如果当前数与变量A的值不同,则需要分两种情况进行讨论:
- 如果B等于0,则令A等于当前数,令B等于1
- 如果B大于0,则令B=B-1
如果当前数与A的值相同,则令B=B+1。遍历结束时,A中存储的数就是要找的数。这个算法的时间复杂度是O(n),空间复杂度为O(1)
int find(vector<int> &a, int len)
{
int A = 0;
int B = 0;
for (int i = 0; i < len; i++)
{
if (B == 0)
{
A = a[i];
B = 1;
}
else
{
if (A == a[i])
{
B++;
}
else
{
B--;
}
}
}
return A;
}