169 多数元素
题目链接:
https://leetcode.cn/problems/majority-element/?envType=study-plan-v2&envId=top-interview-150
题目描述:
常规解法(暴力解)
思路:
- 获取数组长度一半作为阈值
- 使用map统计数组中每个值出现的次数
- 遍历map如果遇到大于阈值的情况直接返回
代码如下:
class Solution {
public int majorityElement(int[] nums) {
int threshold = nums.length / 2;
Map<Integer, Integer> cache = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
cache.put(nums[i], cache.getOrDefault(nums[i], 0) + 1);
if (cache.getOrDefault(nums[i], 0) > threshold) {
return nums[i];
}
}
// 处理编译报错返回 题目已经给出不会出现这种情况
return 0;
}
}
成功AC
优化
看了其他大神的题解才明白的,hhh
数组中出现最多的数为众数,众数的值我们将众数的值标为1其他值为-1,这样将这个数组加起来一定是大于0的,在遍历的过程中出现了和为0的情况,那么众数一定会出现在为遍历的部分,那么前半部分就可以舍弃。继续在为遍历的部分找即可
- 建立sum变量,用于统计数组和,默认值为0
- 如果sum=0,将当前值设为众数
- 如果sum不为0,查看当前值是否为我们标记的众数,如果是sum+1,如果不是sum-1
- 遍历完数组后返回众数
class Solution {
public int majorityElement(int[] nums) {
int sum = 0;
int res = 0;
for (int num : nums) {
if (sum == 0) {
// 如果sum 是0 那么后面的数组加起来一定是大于0 更新当前值为众数
res = num;
}
sum += num == res ? 1 : -1;
}
return res;
}
}
时间复杂度O(N) 空间复杂度O(1)
晚安好梦