几乎唯一子数组的最大和

image

一、集合转数组的代码解释
Integer[] a = nums.toArray(Integer[]::new);

  1. 整行作用:List → Integer[] 数组
  2. Integer[]::new方法引用,代表新建 Integer 数组
  3. 目的:让 toArray() 返回正确类型,而不是 Object 数组

等价于:
Integer[] a = nums.toArray(new Integer[0]);

两者的区别

  1. new Integer[0] = 传空数组 → 集合发现数组太小,替你创建了一个数组,原数组会被扔掉,浪费一点性能(创建了2个数组)
  2. Integer[]::new = 传造数组的方法 → 集合根据方法替你创建一个大小合适的数组,性能最优(只创建了一个数组)
  3. 你以后永远用 Integer[]::new 就对了!(Java8+新写法,方法引用)

二、哈希表的代码解释:

Map<Integer,Integer> cnt = new HashMap<>();

核心作用:创建一个 “计数器 / 统计表”
专门用来统计数字出现的次数

  • Map:Java 里的键值对容器(左边是 key,右边是 value)

  • <Integer, Integer>
    第一个 Integer:要统计的数字(比如 1、2、3)
    第二个 Integer:这个数字出现的次数

  • cnt:是 count 的缩写,意思就是计数

  • new HashMap<>():创建一个空的 Map 容器

三、统计Map中键出现的频率
cnt.merge(a[i], 1, Integer::sum);

merge 是 Map 自带的计数专用方法,专门用来简化统计。

翻译一下

运行
map.merge(键, 要加的值, 重复时怎么算)
你这行:

运行
cnt.merge(a[i], 1, Integer::sum);

意思就是

  1. 如果 a [i] 不存在 → 存入 a[i] → 1
  2. 如果 a [i] 已存在把原来的值 + 1
  3. Integer::sum = 两个数相加

与传统写法的区别

写法 代码 优点 缺点 风格
merge cnt.merge(k,1,Integer::sum) 超级短、优雅、一行搞定 必须 Java 8+ 现代高级
getOrDefault+put put(k, getOrDefault+1) 易懂、兼容性好、所有 Java 版本通用 代码稍长 传统经典

四、cnt.size() 代码解释

cnt.size()
= Map 里有多少个不同的 key
= 数组里有多少个不重复的数字

简单记:

  • 元素总数:用 list.size()
  • 不重复元素个数:用 map.size()

五、cnt.get()和cnt.remove()代码解释

int c = cnt.get(out);
   if (c > 1) {
        cnt.put(out, c - 1);
   } else {
        cnt.remove(out);
       }

int c = cnt.get(out);
-> 拿到数字 out 当前的出现次数 c

cnt.put(out, c - 1);
-> 把次数减 1,再存回去

cnt.remove(out);
-> 直接删掉这个数字

Java代码实现如下:

class Solution {
    public long maxSum(List<Integer> nums, int m, int k) {
        Integer[] a = nums.toArray(Integer[]::new);  

        long res = 0;
        int n = a.length;
        long sum = 0;

        Map<Integer,Integer> cnt = new HashMap<>();

        for(int i = 0;i<n;i++){
            sum += a[i];
            cnt.merge(a[i],1,Integer::sum);

            if(i-k+1<0){
                continue;
            }

            if(cnt.size()>=m){
                res = Math.max(res,sum);
            }

            int out = a[i-k+1];
            sum-=out;
            int c = cnt.get(out);
            if(c>1){
                cnt.put(out,c-1);
            }else{
                cnt.remove(out);
            }
        }

        return res;
    }
}

特别注意

  • 求和sum和结果res必须使用long类型
  • 输入的数据过大时使用int会导致整数溢出
posted @ 2026-05-27 10:58  ZealousMclaren  阅读(6)  评论(0)    收藏  举报