题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路
1.练习HashMap运用,统计就完事了;
2.排序,取中值;
3.无敌-摩尔投票法。
摩尔投票法:
票数和: 由于众数出现的次数超过数组长度的一半;若记 众数 的票数为 +1 ,非众数 的票数为 −1 ,则一定有所有数字的 票数和 >0 。
票数正负抵消: 设数组 nums 中的众数为 x ,数组长度为 n 。若 nums 的前 a 个数字的 票数和 =0 ,则 数组后 (n-a) 个数字的 票数和 一定仍 >0 (即后 (n-a)个数字的 众数仍为 x )。
就很清奇的思路,属实好。
代码
1.HashMap练习。
import java.util.HashMap;
import java.util.Map;
class Solution {
public static int majorityElement(int[] nums) {
// 创建hashmap, 数-次数
HashMap<Integer, Integer> hash = counter(nums);
// 遍历,选出长度大于一半的
int res = MapEntry(hash, nums);
return res;
}
public static HashMap<Integer, Integer> counter(int[] nums) {
HashMap<Integer, Integer> count = new HashMap<Integer, Integer>();
for (int num : nums) {
if (count.containsKey(num)) {
int old_v = count.get(num);
count.put(num, old_v + 1);
} else {
count.put(num, 1);
}
}
return count;
}
public static int MapEntry(HashMap<Integer, Integer> hashmap, int[] nums) {
int res = 0;
for (Map.Entry<Integer, Integer> entry : hashmap.entrySet()) {
if (entry.getValue() > (nums.length / 2)) {
res = entry.getKey();
}
}
return res;
}
}
2.排序不写了;
3.摩尔投票法
class Solution {
public int majorityElement(int[] nums) {
int x = 0, votes = 0;
for(int num : nums){
if(votes == 0) x = num;
votes += num == x ? 1 : -1;
}
return x;
}
}