持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
题目
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。
解题思路
关键词:数字出现次数超出一半
关键信息:数字必然存在、数组无规律排序。
集合解法
根据题意可知该数字出现次数是超过数组长度一半及以上。那么如果该数组是有序的那么该数字是不是就在数组的中间位置范围。这或许需要想象一下,当一个数组有序并且一个数字超过一半那在中间位置肯定就是该值了。
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
但使用到API方法算是高级解法了,不过也是特殊解题思路。
哈希解法
哈希解法原理是创建一个hash表统计数组中每个数字出现个数,在遍历整个数组过程中若其中一个数字统计时出现超过数字长度的一半时说明该数就是结果了。
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
int n = nums.length / 2; // 数组一半长度
for(int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1); // 存入统计该数出现次数
if(map.get(num) > n) { // 获取该数出现次数并和数组一半长度比较
return num;
}
}
return 0;
}
巧解法
另外一种巧妙解法是利用题意(数字出现次数是超过数组长度一半及以上),因此如果一个数超过一半该数遍历统计过程中出现次数肯定是最多了。
- 通过遍历数组,当统计当前数非本数字时-1否则+1。
- 当统计出现次数变成0时切换到其他数重新统计。
- 由于超出数组长度一半因此统计过程中不管怎么切换到其他数最终还是会回到该数字。
public int majorityElement(int[] nums) {
int count = 0;
int maxValue = 0;
for (int num : nums) {
if (count == 0) {
maxValue = num;
}
count += (num == maxValue) ? 1 : -1; //如果等于该数字则+1否则-1
}
return maxValue;
}
参考
- 来源:力扣(LeetCode)