目录
题目
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:[3,2,3]
输出:3
方法① 排序
数组(长度为n)排完序以后,第n/2个位置上的数就是所要求的。
假设6个数,多数元素至少有4个,x x x x x x 或 x x x x x x
假设5个数,多数元素至少有3个,x x x x x 或 x x x x x
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
}
方法② 哈希表
用哈希表来存储每个元素和它出现的次数,返回哈希表中值最大的那个键即可。
class Solution {
public Map<Integer, Integer> countNums(int []nums) {
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
for(int num : nums) {
if(!counts.containsKey(num)) {
counts.put(num,1);
} else {
counts.put(num, counts.get(num)+1);
}
}
return counts;
}
public int majorityElement(int[] nums) {
Map<Integer, Integer> counts = countNums(nums);
Map.Entry<Integer, Integer> majorityEntry = null;
for(Map.Entry<Integer, Integer> entry : counts.entrySet()) {
if(majorityEntry == null || entry.getValue() > majorityEntry.getValue()) {
majorityEntry = entry;
}
}
return majorityEntry.getKey();
}
}
方法③ Boyer-Moore 投票算法
详细步骤
维护一个候选众数 candidate 和它出现的次数 count。初始时 candidate 可为任意值,count 为 0。
遍历数组 nums 中的所有元素,对于每个元素 x,在判断 x 之前,如果 count 的值为 0,我们先将 x 的值赋予 candidate,随后我们判断 x:
如果 x 与 candidate 相等,那么计数器 count 的值增加 1,
如果 x 与 candidate 不等,那么计数器 count 的值减少 1。
在遍历完成后,candidate 即为整个数组的众数。
投票算法证明
- 如果候选人不是maj,则 maj, 会和其他非候选人一起反对 会反对候选人,所以候选人一定会下台(maj==0时发生换届选举)
- 如果候选人是maj , 则maj 会支持自己,其他候选人会反对,同样因为maj 票数超过一半,所以maj 一定会成功当选
class Solution {
public int majorityElement(int[] nums) {
int count = 0;
Integer candidate = null;
for(int num:nums) {
if(count == 0) {
candidate = num;
}
count += (num == candidate) ? 1 : -1;
}
return candidate;
}
}