求长度为k的无重复子数组最大和的flag逻辑问题求助
问题描述
给定整数数组nums和整数k,找出满足以下条件的所有子数组的最大子数组和:
- 子数组长度为k;
- 子数组中所有元素均不重复。
若没有符合条件的子数组,返回0。
问题分析与现有尝试
我尝试用canIcount标记是否可计算当前子数组和,用字典记录元素频率,出现重复元素时将canIcount设为false。但存在多处重复时,无法正确判断何时将canIcount重置为true,导致第三个测试用例无法通过。
现有代码
class Solution: def maximumSubarraySum(self, a, k): sumSoFar, toReturn, i, j = 0, 0, 0, 0 canIcount = True eleToFreq = dict() N = len(a) if len(set(a)) < k: # Handle all-duplicate case return 0 while j < N: if j >= k - 1: if a[j] in eleToFreq: eleToFreq[a[j]] += 1 canIcount = False else: eleToFreq[a[j]] = 1 sumSoFar += a[j] if canIcount: toReturn = max(toReturn, sumSoFar) if eleToFreq[a[i]] >= 1: eleToFreq[a[i]] -= 1 else: eleToFreq.pop(a[i]) sumSoFar -= a[i] i += 1 j += 1 else: if a[j] in eleToFreq: eleToFreq[a[j]] += 1 canIcount = False else: eleToFreq[a[j]] = 1 sumSoFar += a[j] j += 1 return toReturn solution = Solution() arr = [1, 5, 4, 2, 9, 9, 9] k = 3 a = solution.maximumSubarraySum(arr, k) print("Output:", a) # Expected output: 15 actual output: 15 arr = [4, 4, 4] k = 3 a = solution.maximumSubarraySum(arr, k) print("Output:", a) # Expected output: 0 actual output: 0 arr = [1,1,1,7,8,9] k = 3 a = solution.maximumSubarraySum(arr, k) print("Output:", a) # Expected output: 24 actual output:0
测试用例结果
- 输入
[1, 5, 4, 2, 9, 9, 9],k=3:期望输出15,实际输出15(正确) - 输入
[4, 4, 4],k=3:期望输出0,实际输出0(正确) - 输入
[1,1,1,7,8,9],k=3:期望输出24,实际输出0(错误)
问题根源
你的canIcount标记是一次性的:一旦某个窗口出现重复元素被设为false,后续滑动窗口时没有重新检查当前窗口是否已经恢复无重复状态。比如第三个测试用例,前三个元素[1,1,1]导致canIcount=false,之后滑动到[7,8,9]时,canIcount依然是false,所以没有计算这个合法窗口的和。
解决思路
放弃单一的canIcount标记,改为动态跟踪当前窗口内的重复元素数量:
- 用哈希表记录窗口内元素的出现频率
- 维护一个变量
duplicate_count,记录当前窗口中出现次数≥2的元素个数 - 每次滑动窗口时,更新哈希表和
duplicate_count:- 移出左边界元素时,如果它的频率从2降到1,说明重复减少,
duplicate_count -=1 - 加入右边界元素时,如果它的频率从1升到2,说明新增重复,
duplicate_count +=1
- 移出左边界元素时,如果它的频率从2降到1,说明重复减少,
- 当
duplicate_count == 0时,当前窗口所有元素唯一,此时计算并更新最大和
修正后的代码
class Solution: def maximumSubarraySum(self, nums, k): n = len(nums) if n < k: return 0 freq = {} current_sum = 0 max_sum = 0 duplicate_count = 0 # 初始化第一个窗口 for i in range(k): num = nums[i] current_sum += num if num in freq: freq[num] += 1 if freq[num] == 2: duplicate_count += 1 else: freq[num] = 1 if duplicate_count == 0: max_sum = current_sum # 滑动窗口 for i in range(k, n): # 移出左边界元素 left_num = nums[i - k] current_sum -= left_num freq[left_num] -= 1 if freq[left_num] == 1: duplicate_count -= 1 if freq[left_num] == 0: del freq[left_num] # 加入右边界元素 right_num = nums[i] current_sum += right_num if right_num in freq: freq[right_num] += 1 if freq[right_num] == 2: duplicate_count += 1 else: freq[right_num] = 1 # 检查当前窗口是否合法 if duplicate_count == 0: if current_sum > max_sum: max_sum = current_sum return max_sum solution = Solution() arr = [1, 5, 4, 2, 9, 9, 9] k = 3 print("Output:", solution.maximumSubarraySum(arr, k)) # 15 arr = [4, 4, 4] k = 3 print("Output:", solution.maximumSubarraySum(arr, k)) # 0 arr = [1,1,1,7,8,9] k = 3 print("Output:", solution.maximumSubarraySum(arr, k)) #24
内容的提问来源于stack exchange,提问作者Karina
相关产品推荐
相关产品推荐

