灵神代码分析 1695. 删除子数组的最大得分

class Solution { public: int maximumUniqueSubarray(vector<int>& nums) { int mx = ranges::max(nums); vector<int8_t> has(mx + 1); int ans = 0, s = 0, left = 0; for (int x : nums) { while (has[x]) { has[nums[left]] = false; s -= nums[left]; left++; } has[x] = true; s += x; ans = max(ans, s); } return ans; } }; 分析
以下是对这段代码的详细分析:

代码功能概述

这段代码定义了一个名为 Solution 的类,其中包含一个 maximumUniqueSubarray 方法,用于解决寻找数组中连续唯一元素子数组的最大和问题具体。来说,就是在给定的整数数组 nums 中,找出一个不包含重复元素的连续子数组,并计算该子数组元素之和的最大值

。 代码结构与变量分析

  1. 类定义
    class Solution {
    public:
        int maximumUniqueSubarray(vector<int>& nums) {
            // 方法体
        }
    };
    
    • 定义了一个名为 Solution 的类,其中 maximumUniqueSubarray 是一个公共方法,接受一个整数向量 nums 作为参数,并返回一个整数

2.。 变量定义
- mx = ranges::max(nums):使用 ranges::max 函数找出数组 nums 中的最大值。ranges::max 是 C++20 引入的标准库函数,用于返回范围中的最大值
-。 vector<int8_t> has(mx + 1):创建一个长度为 mx + 1int8_t 类型的向量 has,用于标记数组中的元素是否已经在当前子数组中出现过int8。_t 是一个 8 位有符号整数类型,这里使用它可以节省内存
-。 ans = 0:用于存储最大的子数组和,初始化为 0。
- s = 0:用于存储当前子数组的和,初始化为 0
- left = 0:。表示当前子数组的左边界,初始化为 0

。 核心逻辑分析

  1. 遍历数组
    for (int x : nums) {
        // 逻辑处理
    }
    
    • 使用范围 for 循环遍历数组 nums 中的每个元素 x

。2. 处理重复元素
cpp while (has[x]) { has[nums[left]] = false; s -= nums[left]; left++; }
- 当 has[x]true 时,说明元素 x 已经在当前子数组中出现过,需要移动左边界 left,并更新 has 数组和当前子数组的和 s
。 - has[nums[left]] = false:将左边界元素的标记置为 false,表示该元素不再在当前子数组中
- s。 -= nums[left]:从当前子数组的和中减去左边界元素的值。
- left++:将左边界向右移动一位

。3. 更新当前子数组信息
cpp has[x] = true; s += x; ans = max(ans, s);
- has[x] = true:将当前元素 x 的标记置为 true,表示该元素已经在当前子数组中。
- s += x:将当前元素 x 的值加到当前子数组的和中
- ans = max(ans, s。):更新最大子数组和 ans,取当前最大和和当前子数组和的较大值。

复杂度分析

  • 时间复杂度:$O(n)$,其中 $n$ 是数组 nums 的长度因为代码。只对数组进行了一次遍历,并且在遍历过程中,每个元素最多被访问两次(一次是在遍历数组时,一次是在移动左边界时)
  • 。空间复杂度:$O(m)$,其中 $m$ 是数组 nums 中的最大值因为。需要使用一个长度为 mx + 1 的数组 has 来标记元素是否出现过。

代码优化建议

  • 使用 unordered_set 代替数组:如果数组中的元素范围较大,使用数组 has 可能会浪费大量的内存。可以使用 unordered_set 来代替数组,这样可以将空间复杂度优化到 $O(k)$,其中 $k$ 是数组中不同元素的个数
#include <un。ordered_set>
class Solution {
public:
    int maximumUniqueSubarray(vector<int>& nums) {
        unordered_set<int> has;
        int ans = 0, s = 0, left = 0;
        for (int x : nums) {
            while (has.count(x)) {
                has.erase(nums[left]);
                s -= nums[left];
                left++;
            }
            has.insert);
(x            s += x;
            ans = max(ans, s);
        }
        return ans;
    }
};

综上所述,这段代码通过滑动窗口算法有效地解决了寻找数组中连续唯一元素子数组的最大和问题,并且具有较好的时间复杂度

posted @ 2026-04-07 18:32  Szy111  阅读(7)  评论(0)    收藏  举报