Question
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
关键词:数组 次数 分型叶法
Solution
sort函数
直接对数组sort,超过一半的数字一定在len/2的位置上。返回来计算这个数字是否超过一半的数量。为了避免遍历整个数组,从len/2向前向后数。
时间复杂度:O(Nlog(N) + N/2)
空间复杂度:O(1)
- Python
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
numbers = sorted(numbers)
t = len(numbers)//2
ans = numbers[t]
count = 0
i = t
while i >=0 and numbers[i]==ans:
count += 1
i -= 1
j = t+1
while j < len(numbers) and numbers[j]==ans:
count += 1
j += 1
if count>t:
return ans
return 0
- C++
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.empty())
return 0;
sort(numbers.begin(), numbers.end());
int temp_ans = numbers[numbers.size()/2];
int count = 0;
for(int i=0; i<numbers.size(); i++)
if(temp_ans == numbers[i])
count++;
return count>(numbers.size())/2? temp_ans:0;
}
};
dic查找
利用dic储存所有数字出现的次数,当某一个数字的次数超过一半,输出对应数字(key)。
时间复杂度:O(N)
空间复杂度:O(N/2)
- Python
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
n = len(numbers)/2
dic = {}
for i in numbers:
if i not in dic.keys():
dic[i] = 1
else:
dic[i] += 1
if dic[i] > n:
return i
return 0
- C++
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
map<int,int> counts;
for(int i=0; i<numbers.size(); i++){
if(counts.find(numbers[i]) == counts.end())
counts[numbers[i]] = 1;
else
counts[numbers[i]]++;
if(counts[numbers[i]] > (numbers.size()/2))
return numbers[i];
}
return 0;
}
};
分型叶法
同时去掉两个不同的数字,如果最后剩下两个一样的数字,说明该数字就是可能的结果。将该数字带回计算出现次数。
时间复杂度:O(N)
空间复杂度:O(1)
- Python
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
same_count = 0
temp_ans = []
for n in numbers:
if same_count == 0:
temp_ans.append(n)
same_count = 1
elif n != temp_ans[-1]:
temp_ans.pop()
same_count -= 1
else:
temp_ans.append(n)
same_count += 1
count = 0
# return temp_ans[0]
if not temp_ans:
return 0
for n in numbers:
if temp_ans[0] == n:
count += 1
return temp_ans[0] if count < len(numbers)/2 else 0
- C++
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
stack<int> temp_ans;
int same_count = 0;
for(int i=0; i<numbers.size(); i++){
if(same_count == 0){
same_count++;
temp_ans.push(numbers[i]);
}
else if(numbers[i] != temp_ans.top()){
same_count--;
temp_ans.pop();
}
else{
same_count++;
temp_ans.push(numbers[i]);
}
}
if(temp_ans.size() == 0)
return 0;
int count = 0;
for(int i=0; i<numbers.size(); i++){
if(numbers[i] == temp_ans.top())
count++;
}
return count>(numbers.size())/2? temp_ans.top():0;
}
};