LeetCode: 剑指 Offer 39. 数组中出现次数超过一半的数字
- 当该数出现的次数大于数组长度的一半时, 排序后, 数组中间的数一定为该数
- 哈希表
- 摩尔投票法 >> 最佳解法
3.1 通过假设众数 >> 相等票数++, 不等票数–, 当票数 == 0 重新假设众数
出现的次数超过数组长度的一半,排序后该数在数组的中间一定存在
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
哈希表
容易想到的方法
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
Integer old = map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
if(old != null && old + 1 > nums.length / 2) {
return nums[i];
}
}
return nums[0];
}
摩尔投票法
public int majorityElement(int[] nums) {
int x = 0;
int p = 0;
for (int i = 0; i < nums.length; i++) {
// 当票数为 0
if(p == 0){
// 设当前 i 的 num 为众数
x = nums[i];
p++;
}
else if(x == nums[i]) p++;
else p--;
}
return x;
}
当题目不存在假设时, 我们还需要加一个验证
public int majorityElement(int[] nums) {
int x = 0;
int p = 0;
for (int i = 0; i < nums.length; i++) {
// 当票数为 0
if(p == 0){
// 设当前 i 的 num 为众数
x = nums[i];
p++;
}
else if(x == nums[i]) p++;
else p--;
}
int count = 0;
for (int i = 0; i < nums.length; i++) {
if(nums[i] == x) count++;
}
if(count <= nums.length / 2) return 0;
return x;
}
>>
解题思路