题目
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
解1-摩尔投票
摩尔投票: 首先请考虑最基本的摩尔投票问题,找出一组数字序列中出现次数大于总数1/2的数字(并且假设这个数字一定存在)。显然这个数字只可能有一个。摩尔投票算法是基于这个事实:每次从序列里选择两个不相同的数字删除掉(或称为“抵消”),最后剩下一个数字或几个相同的数字,就是出现次数大于总数一半的那个。
图解模拟摩尔投票
视频讲解
- count为当前元素个数,major当前存活值
- count=0:
说明前面的数可以组成两两不同的一对数进行抵消完毕
从新确定 count=1 major=x- coun!=0 :
1. major==x count++
2. major1=x count–- 证明摩尔投票
class Solution {
public int majorityElement(int[] nums) {
int major=0;
int count=0;
for(int x:nums){
if(count==0){
count=1;
major=x;
}else{
if(major==x){
count++;
}else{
count--;
}
}
}
//证明major就是超过一半的数,这个数一定存在歧视就不用证明
int t=0;
if(count>0){
for(int x:nums){
if(x==major){
t++;
}
if(t>nums.length/2){
return major;
}
}
}
return -1;
}
}
解2- HashMap
- map统计每个元素的个数
- 遍历map找超过半数的值
class Solution {
public int majorityElement(int[] nums) {
Map<Integer,Integer> map=new HashMap<>();
for(int x:nums){
map.put(x,map.getOrDefault(x,0)+1);
}
int len=nums.length;
for(int x:map.keySet()){
if(map.get(x)*2>len){
return x;
}
}
return -1;
}
}