题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
看到这个就想到了c++中的map,C++中map提供的是一种键值对容器,里面的数据都是成对出现的。每对中的第一个值称之为关键字(key),每个关键字只能在map中出现一次;第二个称之为该关键字的对应值(values)。
因为只可能有一个数出现的次数count是大于长度的一半的。因此通过count>len/2,可以找到唯一对应的numbers[i]。
先对numbers进行排序,这样相同的数字就排列在一起。如果前后两数相等count的值就加1,把count作为键值,numbers[i]为values。
c++实现:
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0)
return 0;
int len = numbers.size();
sort(numbers.begin(),numbers.end());
int count=1;
map<int,int> n;
for(int i=0;i<len;i++)
{
if(numbers[i]==numbers[i+1])
count++;
if(numbers[i]!=numbers[i+1])
{
n.insert(pair<int,int>(count,numbers[i]));
count=1;
}
if(count>len/2)
return numbers[i];
}
return 0;
}
};
因为用到了sort函数,时间复杂度为O(n*logn)。考虑有没有更优化的情况。而且这里存在问题,虽然count>len/2的值是唯一的,但是对于其他的数字选择了忽略次数对应关系,即有可能有其他的两个数count都为2。
方法二:
不使用sort函数,在map中,对不存在的键值自动分配空间,对应values值为0
用numbers[i]的值作为键值,这样键值对应count就是这个数的次数,也就是数-次数这个组合。numbers[i]出现,count就自增1,也就是相同数字出现时,count的值加一。注意++在左,先自增再赋值。
这个方法的时间复杂度为O(n),也比上面的方法更直观一些
推荐算法(c++)
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0)
return 0;
int len = numbers.size();
sort(numbers.begin(),numbers.end());
int count=1;
map<int,int> n;
for(int i=0;i<len;i++)
{
count=++n[numbers[i]]; //n[numbers[i]]的初始值是0,因此要先++
if(count>len/2)
return numbers[i];
}
return 0;
}
};
方法三:
还在讨论区中看到一个很巧妙的方法,这里也放出来。
如果存在这个数,那么这个数的count一定比其他数加起来的count还多,所以如果num是这个数,那么他的count永远不会被减至零。举几个例子就能很清楚的理解这个方法的思路了。
比如1,1,2,3,1。1,2,1,3,1,2,1
想象一下1,1,2,3,1.这样就算前面count减至零了后面num还是等于1
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) {
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;
python实现:
python用到的是字典,也是一个key值对应一个values值
这里用numbers[i]的值作为key值,count作为values值,得到每个数字出现的次数的一个字典
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
dic={}
n=len(numbers)
for i in range(n):
if numbers[i] in dic:
dic[numbers[i]]+=1
else:
dic[numbers[i]]=1
if dic[numbers[i]]>n/2:
return numbers[i]
return 0