一、题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
二、思路分析:
1、先后两次遍历数组,第一次遍历数组并用map统计数组中每个数字出现的次数;第二次遍历数组找出出现次数超过数组长度一半的数字。
C++:
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int length = numbers.size();
if(length == 0){
return 0;
}
//遍历数组,统计每个数字出现的次数
map<int,int> numMap;
for(int i=0; i<length; i++){
numMap[numbers[i]]++;
}
//遍历数组,找出第一个出现次数超过数组长度一半的数字
for(int i=0; i<length; i++){
if(numMap[numbers[i]] > length/2){
return numbers[i];
}
}
return 0;
}
};
python:
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, nums):
# write code here
length = len(nums)
if length == 0:
return 0
numMap = {}
for num in nums:
if num not in numMap:
numMap[num] = 1
else:
numMap[num] += 1
for num in nums:
if numMap[num] > length//2:
return num
return 0
2、思路:https://www.bilibili.com/video/BV187411W7A9?from=search&seid=6211879220294896728
在上述视频中博主介绍了四种方法,这里实现的是第四种。
方法:第一次遍历数组,找到数组中出现次数最多的数字result;第二次遍历数组,判断数字result出现的次数是否超过数组长度的一半。
第一次遍历数组的遍历规则:初始化result为数组的第一个元素,并初始化其出现次数times为1。如果下一个数字和result相同,则result对应的次数加1;如果不同,次数减1。如果次数times减为零,将下一个数字初始化为result,并初始化该数字出现次数为1。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么遍历完数组后得到的result就是出现次数最多的元素。再判断出现次数是否超过数组长度的一半。
C++实现:
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int result = numbers[0];//从第一个元素开始,初始化出现的次数为1
int times = 1;
for(int i = 1; i < numbers.size(); ++i){//遍历数组中的每个元素,若与前一个元素相同,则则该元素出现的次数加1,否则减1,当次数为0的时候初始化下一个元素出现的次数为1
if(times == 0){
// 更新result的值为当前元素,并置次数为1
result = numbers[i];
times = 1;
}
else if(numbers[i] == result){
times++;
}
else{
times--;
}
}
//经过上面的for循环,times对应的元素result就是数组中出现次数最多的一个元素,但具体出现的次数并不知道
//下面判断次这个元素出现的次数是不是超过数组长度的一半
times = 0;
for(int i=0; i<numbers.size(); i++){
if(result == numbers[i]){
times++;
}
}
return (times > (numbers.size() >> 1)) ? result : 0;//右移一位相当于除2,左移乘2
}
};
python实现:
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
result = numbers[0]
times = 1
for i in range(1,len(numbers)):
if times == 0:
result = numbers[i]
times = 1
elif numbers[i]==result:
times += 1
else:
times -= 1
times = 0
for val in numbers:
if val==result:
times += 1
return result if times>len(numbers)//2 else 0