当前位置: 面试刷题>> 最大子数组Ⅱ (经典算法题500道)


### 题目描述 **最大子数组 II** 给定一个整数数组 `nums` 和一个整数 `k`,你需要找到该数组中和最大的子数组,但要求子数组中最多只能包含 `k` 个不同的整数。返回这个子数组的最大可能和。 **示例 1**: ``` 输入: nums = [1,5,4,2,9,9,9], k = 3 输出: 20 解释: 子数组 [5,4,2,9,9,9] 的和是 29,但是它包含 4 个不同的整数。子数组 [1,5,4,2,9] 的和是 21,但是它包含 5 个不同的整数。子数组 [5,9,9,9] 的和是 23,但是它包含 2 个不同的整数。所以最优解是 [4,2,9,9,9],和是 20,并且只包含 3 个不同的整数。 ``` **示例 2**: ``` 输入: nums = [3,9,3], k = 2 输出: 9 解释: 子数组 [9] 的和是 9,包含 1 个不同的整数。 ``` **注意**: 1. `1 <= nums.length <= 10^5` 2. `-10^4 <= nums[i] <= 10^4` 3. `1 <= k <= nums.length` ### 解题思路 这个问题可以通过滑动窗口和哈希表结合的方法来解决。我们需要维护一个窗口,窗口内的元素种类不超过 `k` 种,并实时计算窗口内元素的总和。当窗口内的元素种类超过 `k` 时,需要移动窗口的左边界,同时从哈希表中移除对应的元素,直到窗口内的元素种类不超过 `k` 为止。 ### PHP 示例代码 ```php function maxSubArraySumWithKDistinct($nums, $k) { $maxSum = PHP_INT_MIN; $currentSum = 0; $left = 0; $distinctCount = array(); for ($right = 0; $right < count($nums); $right++) { if (!isset($distinctCount[$nums[$right]])) { $distinctCount[$nums[$right]] = 1; } else { $distinctCount[$nums[$right]]++; } $currentSum += $nums[$right]; while (count($distinctCount) > $k) { $currentSum -= $nums[$left]; $distinctCount[$nums[$left]]--; if ($distinctCount[$nums[$left]] == 0) { unset($distinctCount[$nums[$left]]); } $left++; } $maxSum = max($maxSum, $currentSum); } return $maxSum; } // 测试 $nums = [1,5,4,2,9,9,9]; $k = 3; echo maxSubArraySumWithKDistinct($nums, $k); // 输出 20 ``` ### Python 示例代码 ```python def maxSubArraySumWithKDistinct(nums, k): max_sum = float('-inf') current_sum = 0 left = 0 distinct_count = {} for right in range(len(nums)): if nums[right] not in distinct_count: distinct_count[nums[right]] = 0 distinct_count[nums[right]] += 1 current_sum += nums[right] while len(distinct_count) > k: current_sum -= nums[left] distinct_count[nums[left]] -= 1 if distinct_count[nums[left]] == 0: del distinct_count[nums[left]] left += 1 max_sum = max(max_sum, current_sum) return max_sum # 测试 nums = [1,5,4,2,9,9,9] k = 3 print(maxSubArraySumWithKDistinct(nums, k)) # 输出 20 ``` ### JavaScript 示例代码 ```javascript function maxSubArraySumWithKDistinct(nums, k) { let maxSum = Number.MIN_SAFE_INTEGER; let currentSum = 0; let left = 0; let distinctCount = {}; for (let right = 0; right < nums.length; right++) { if (!(nums[right] in distinctCount)) { distinctCount[nums[right]] = 0; } distinctCount[nums[right]]++; currentSum += nums[right]; while (Object.keys(distinctCount).length > k) { currentSum -= nums[left]; distinctCount[nums[left]]--; if (distinctCount[nums[left]] === 0) { delete distinctCount[nums[left]]; } left++; } maxSum = Math.max(maxSum, currentSum); } return maxSum; } // 测试 const nums = [1,5,4,2,9,9,9]; const k = 3; console.log(maxSubArraySumWithKDistinct(nums, k)); // 输出 20 ``` 码小课网站中有更多相关内容分享给大家学习,包括但不限于算法、数据结构、编程技巧等,欢迎大家访问学习。
推荐面试题