1500分的题目,确实有实力,不过还是我略胜一筹

Problem: 2841. 几乎唯一子数组的最大和

  1. 思路
  2. 解题方法
  3. 复杂度
  4. Code

思路

子数组定长 ,一定的条件限制,已经是条件反射了。立即推:滑动窗口

解题方法

怎么滑?边界值出去的时候要怎么做?

  • 怎么滑?定长的滑动窗口基本上直接确定这样的整体逻辑

    js 复制代码
       while (right - left + 1 > k) {
            sum -= nums[left]
            left++;
        }
        
        sum += nums[right]
    
        if (right - left + 1 === k) {
            ans = Math.max(ans, sum)
        }

    上述代码可以求全部的长度为k的子数组的sum的最大值。接下来我们就是要过滤那些不符合题意的子数组(即只选取【几乎唯一子数组】)

  • 到底该怎么排除 那些不符合题意 的长度同样也为k子数组呢?

    • 确保至少有m个不同的数字,也可以理解成重复数字的总数<= k - m
    • 因此,咱们可以用repeatCount来记录当前长度为k的子数组中,重复数字的个数。
  • 于是原来的代码就可以写成这样,只有满足题干条件的子数组 ,才有资格去和ans作比较。

    js 复制代码
            if (right - left + 1 === k&& repeatCount <= k - m) {
            ans = Math.max(ans, sum)
        }
  • 接下来,问题就转变成了"如何去维护repeatCount的值",什么时候加?什么时候减?

  • 于是我们通过一个hashMap来记录当前遍历的数字是否出现过。

    • 如果出现过,则repeatCount++,

    • 那么什么时候执行repeatCount--呢?

      • 当数字从滑动窗口中被移出时,且通过hashMapget到此数字的值大于1时 ,才执行repeatCount--。因为当这个数字都要被踢出滑动窗口了,它在hashMap中记录的值还是1的话,就说明这个数字一直以来都没有重复过,因此没必要让repeatCount--

最终我们得到如下代码:

js 复制代码
 for (let right = 0; right < nlen; right++) {
        while (right - left + 1 > k) {
            if (hash.get(nums[left]) > 1) {
                if (repeatCount > 0) {
                    repeatCount--;
                }
            }
            if (hash.get(nums[left]) > 0) {
                hash.set(nums[left], hash.get(nums[left]) - 1)
            }
            if (hash.get(nums[left]) === 0) {
                hash.delete(nums[left])
            }
            sum -= nums[left]
            left++
        }

        if (hash.has(nums[right])) {
            hash.set(nums[right], hash.get(nums[right]) + 1)
            repeatCount++;
        }
        else {
            hash.set(nums[right], 1)
        }
        sum += nums[right]
        if (right - left + 1 === k && repeatCount <= k - m) {
            ans = Math.max(ans, sum)
        }

复杂度

时间复杂度:

O(n)

空间复杂度:

O(n)

Code

js 复制代码
/**
 * @param {number[]} nums
 * @param {number} m
 * @param {number} k
 * @return {number}
 */
var maxSum = function (nums, m, k) {

    let left = 0;
    let nlen = nums.length;
    let hash = new Map();
    let repeatCount = 0;
    let sum = 0;
    let ans = 0;
    for (let right = 0; right < nlen; right++) {
        while (right - left + 1 > k) {
            if (hash.get(nums[left]) > 1) {
                if (repeatCount > 0) {
                    repeatCount--;
                }
            }
            if (hash.get(nums[left]) > 0) {
                hash.set(nums[left], hash.get(nums[left]) - 1)
            }
            if (hash.get(nums[left]) === 0) {
                hash.delete(nums[left])
            }


            sum -= nums[left]
            left++
        }
        if (hash.has(nums[right])) {
            hash.set(nums[right], hash.get(nums[right]) + 1)
            repeatCount++;
        }
        else {
            hash.set(nums[right], 1)
        }
        sum += nums[right]
        if (right - left + 1 === k && repeatCount <= k - m) {
            ans = Math.max(ans, sum)
        }
    }


    return ans;

};
相关推荐
兰令水4 分钟前
hot100【acm版】【2026.7.25/26打卡-java版本】
java·算法·排序算法
音视频工程实战1 小时前
PromptQL 新手入门与实战指南
数据库·sql·算法
wabs6661 小时前
关于图论【卡码网104.建造最大岛屿的思考】
数据结构·算法·图论
玖玥拾1 小时前
LeetCode 27 移除元素
算法·leetcode
冻柠檬飞冰走茶2 小时前
PTA基础编程题目集 7-15 计算圆周率(C语言实现)
c语言·开发语言·数据结构·算法
问商十三载2 小时前
AI 引擎生成式优化两种思路怎么选?2026 对比分析附选型方法
人工智能·算法
hanlin033 小时前
刷题笔记:力扣第704、977、209题(数组相关)
笔记·算法·leetcode
陕西企来客4 小时前
生成式引擎优化(GEO)行业白皮书:从流量分配到认知占有的战略跃迁
人工智能·算法·机器学习·技术好geo优化
大鱼>4 小时前
ROS2+强化学习:机械臂抓取与Sim-to-Real迁移实战
人工智能·深度学习·算法