摩尔投票算法 力扣169,229,1150,2404

力扣169,229,1150,2404

Posted by Hilda on March 13, 2025

下面2道已经做过,记录1150和2404两道题,这4道题都是和摩尔投票算法相关的。

169

169解法

229

229解法

1150. 检查一个数是否在数组中占绝大多数

1150. 检查一个数是否在数组中占绝大多数

1
2
3
4
5
6
7
8
9
class Solution {
    public boolean isMajorityElement(int[] nums, int target) {
        int count = 0;// 计数器
        for (int i : nums) {
            if (target == i) count++;
        }
        return count > nums.length / 2;       
    }
}

2404. 出现最频繁的偶数元素

2404. 出现最频繁的偶数元素

解法1:HashMap

写了个很垃圾的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
    public int mostFrequentEven(int[] nums) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int n : nums) {
            if (n % 2 == 0 && !map.containsKey(n)) {
                map.put(n, 1);
            } else if (map.containsKey(n)) {
                map.put(n, map.get(n) + 1);
            }
        }
        int max = 0;
        List<Integer> res = new ArrayList<>();
        for (Integer key : map.keySet()) {
            int c = map.get(key);
            if (c > max) {
                max = c;
                res.clear();
                res.add(key);
            } else if (c == max) {
                res.add(key);
            }
        }
        if (res.size() > 1) return Collections.min(res);
        if (res.size() == 1) return res.get(0);
        return -1; // 全部都是奇数   
    }
}

image-20250313111651831

我看到一个和我一样用HashMap的,但是比我简洁:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
    public int mostFrequentEven(int[] nums) {
        Map<Integer, Integer> cnt = new HashMap<>();
        for (int x : nums) {
            if (x % 2 == 0) {
                cnt.merge(x, 1, Integer::sum);
            }
        }
        int ans = -1, mx = 0;
        for (var e : cnt.entrySet()) {
            int x = e.getKey(), v = e.getValue();
            if (mx < v || (mx == v && ans > x)) {
                ans = x;
                mx = v;
            }
        }
        return ans;
    }
}

image-20250313130947481

注:

1.若 x 为偶数,使用 merge 方法更新 cnt:

  • 若键 x 不存在,则插入键值对 (x, 1)。
  • 若键 x 已存在,则将其值与 1 相加(通过 Integer::sum 函数)。

2.比较逻辑:

  • 若当前频率 v 大于最大频率 mx,更新 ans 为 x,mx 为 v。
  • 若 v 等于 mx 且当前 x 小于 ans,更新 ans 为 x(确保返回最小值)。

解法2:单次遍历+数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
    public int mostFrequentEven(int[] nums) {
        int[] arr = new int[50001];
        int ans = -1, mx = 0;
        for (int i : nums) {
            if (i % 2 == 0) {
                int freq = ++arr[i / 2];
                if (freq > mx || (freq == mx && i < ans)){
                    mx = freq;
                    ans = i;
                }
            }
        }
        return ans;
    }
}

image-20250313131755148

注:

由于元素值范围固定且较小(( 0 ) 到 10^5),可用固定大小的数组替代 HashMap,仅记录偶数频率:

  • 数组大小为 10^5 / 2 + 1 = 50001(仅偶数)。