目录
最大唯一元素子数组和 —— 滑动窗口解法详解
题目描述
给定一个正整数数组 nums,你需要从中删除一个连续子数组,该子数组的所有元素互不相同(没有重复元素)。删除这个子数组的得分定义为子数组内元素之和。
请你返回只删除一个子数组能够获得的最大得分。
换句话说,就是求一个最长无重复元素的连续子数组,使得该子数组的元素和最大。
题目示例
示例 1
输入:nums = [4,2,4,5,6]
输出:17
解释:最优子数组是 [2,4,5,6],和为 2+4+5+6=17。
示例 2
输入:nums = [5,2,1,2,5,2,1,2,5]
输出:8
解释:最优子数组是 [5,2,1] 或 [1,2,5],和为 8。
解题分析
题目要求的是找到一个连续子数组,这个子数组没有重复元素,并且它的元素和最大。
这是一个典型的“最长无重复子串/子数组”问题的变种:
- 我们需要的不是最长无重复子数组的长度,而是最大和。
- 子数组必须是连续的。
根据这些要求,**滑动窗口(双指针)**是解决此类问题的经典方法。
解题方法:滑动窗口
滑动窗口核心思想
- 维护两个指针
left和right,表示当前考察的子数组边界。 - 用一个集合(
seen)存储当前窗口内的元素,保证窗口内元素唯一。 - 使用一个变量
window_sum维护当前窗口内元素的和。 - 使用一个变量
max_sum来维护迄今为止遇到的最大和。
算法步骤
- 初始化:
left = 0,right = 0,空集合seen,window_sum = 0,max_sum = 0。 - 右指针
right从左向右遍历数组元素:
-
- 如果当前元素
nums[right]不在集合seen中,直接将其加入seen,window_sum加上这个元素。 - 如果当前元素在
seen中,说明有重复元素出现,开始移动左指针left:
- 如果当前元素
-
-
- 不断移除
nums[left],从seen中删除对应元素,同时从window_sum减去它的值。 - 直到
nums[right]不再在seen中为止。
- 不断移除
-
- 每次右指针右移后,更新
max_sum = max(max_sum, window_sum)。 - 遍历结束后,
max_sum就是最大无重复元素子数组的和。
代码实现(Python)
from typing import List
class Solution:
def maximumUniqueSubarray(self, nums: List[int]) -> int:
seen = set()
left = 0
window_sum = 0
max_sum = 0
for right in range(len(nums)):
# 如果遇到重复元素,左指针右移直到移除重复元素
while nums[right] in seen:
seen.remove(nums[left])
window_sum -= nums[left]
left += 1
# 添加当前元素
seen.add(nums[right])
window_sum += nums[right]
# 更新最大和
max_sum = max(max_sum, window_sum)
return max_sum
复杂度分析
- 时间复杂度:O(n),其中 n 是数组长度。每个元素最多被左右指针访问两次(一次加入窗口,一次移出窗口)。
- 空间复杂度:O(k),k 是窗口最大长度,即无重复元素的最长子数组长度,用于存储集合中的元素。
示例说明
示例 1
nums = [4,2,4,5,6]
- 初始化:
left=0,right=0,seen={},window_sum=0,max_sum=0 - right=0: 4不重复,加入,窗口和=4,max_sum=4
- right=1: 2不重复,加入,窗口和=6,max_sum=6
- right=2: 4重复,左指针移动,移除第一个4,窗口和=2,left=1;再次检查,4不重复,加入窗口和=6,max_sum=6
- right=3: 5不重复,加入,窗口和=11,max_sum=11
- right=4: 6不重复,加入,窗口和=17,max_sum=17
- 结束,最大和为17,对应子数组
[2,4,5,6]
示例 2
nums = [5,2,1,2,5,2,1,2,5]
- 右指针移动加入元素,遇到重复时左指针右移移除元素
- 最大无重复子数组为
[5,2,1]或[1,2,5],和为 8
总结
- 该题是典型的滑动窗口应用,适合用双指针动态维护无重复子数组。
- 关键在于使用一个集合快速判断重复,和维护当前窗口元素和。
- 该算法时间效率高,能应对较大规模输入。
- 思路也适用于“最长无重复子串”这类类似问题。
832

被折叠的 条评论
为什么被折叠?



