1.题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
2.算法描述
方法1:
思想:统计所有数字出现的次数,然后检查是否存在出现次数大于数组长度一半的数字。
以数字为键,数字出现的次数为值建立一个hash表,然后以键遍历hash表,一旦出现了键对应的值大于数组长度的一半,则该键就是答案。
方法2:(推荐)
方法1需要开辟一个辅助hash表,有没有可能不用额外的空间呢,即
呢?有的。
假如数组中存在一个数字出现的次数大于数组长度的一半,那么,
当然最后找出的这个数我们需要再次遍历数组验证是否确实是出现超过数组的一半。
3.代码描述
3.1.Java代码
//方法1
import java.util.*;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null || array.length==0)
return 0;
if(array.length==1)
return array[0];
//统计各个数字出现的次数
Map<Integer, Integer> map = new HashMap<>();
for(int n: array){
map.put(n, map.getOrDefault(n, 0) + 1);
}
int ans = 0;
for(int key: map.keySet()){
if(map.get(key)*2>array.length){
ans = key;
break;
}
}
return ans;
}
}
//方法2:
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array==null || array.length==0)
return 0;
if(array.length==1)
return array[0];
int num = array[0], count = 1;
for(int i=1; i<array.length; i++){//每次遍历相邻的两个数 如果不一样 就当作将其从数组中去掉
if(count==0){
num = array[i];
count = 1;
}
else{
if(num == array[i])
count++;
else
count--;
}
}
//验证是否出现次数确实是超过数组一半
count = 0;
for(int n: array){
if(num == n)
count++;
}
if(count*2>array.length)
return num;
else
return 0;
}
}
3.2.Python代码
//方法1:
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if not numbers:
return 0
maps = {}
for n in numbers:
maps[n] = maps.get(n,0) + 1
ans = 0
for k, v in maps.items():
if v*2 > len(numbers):
ans = k
break
return ans
#方法2
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if not numbers:
return 0
length = len(numbers)
if length == 1:
return numbers[0]
num = numbers[0]
count = 1
for i in range(1, length):
if count == 0:
num = numbers[i]
count = 1
else:
if num == numbers[i]:
count += 1
else:
count -= 1
count = numbers.count(num)
if count*2>length:
return num
else:
return 0