给你一个正整数数组 nums
,请你从中删除一个含有 若干不同元素 的子数组。删除子数组的 得分 就是子数组各元素之 和 。
返回 只删除一个 子数组可获得的 最大得分 。
如果数组 b
是数组 a
的一个连续子序列,即如果它等于 a[l],a[l+1],...,a[r]
,那么它就是 a
的一个子数组。
示例 1:
输入:nums = [4,2,4,5,6] 输出:17 解释:最优子数组是 [2,4,5,6]
示例 2:
输入:nums = [5,2,1,2,5,2,1,2,5] 输出:8 解释:最优子数组是 [5,2,1] 或 [1,2,5]
提示:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^4
提示 1
The main point here is for the subarray to contain unique elements for each index. Only the first subarrays starting from that index have unique elements.
提示 2
This can be solved using the two pointers technique
解法:滑动窗口
class Solution {
public int maximumUniqueSubarray(int[] nums) {
int ans = Integer.MIN_VALUE;
int sum = 0;
Map<Integer, Integer> window = new HashMap<>();
int left = 0;
int right = 0;
while (right < nums.length) {
sum += nums[right];
window.merge(nums[right], 1, Integer::sum);
while (window.get(nums[right]) > 1) {
window.merge(nums[left], -1, Integer::sum);
sum -= nums[left];
left++;
}
ans = Math.max(ans, sum);
right++;
}
return ans;
}
}
复杂度分析
- 时间复杂度:O(n),n 是 数组 nums 的长度。
- 空间复杂度:O(n)。
另一种写法:
class Solution {
public int maximumUniqueSubarray(int[] nums) {
int ans = Integer.MIN_VALUE;
int sum = 0;
Map<Integer, Integer> window = new HashMap<>();
int left = 0;
int right = 0;
while (right < nums.length) {
while (window.containsKey(nums[right])) {
window.remove(nums[left]);
sum -= nums[left];
left++;
}
window.put(nums[right], 1);
sum += nums[right];
ans = Math.max(ans, sum);
right++;
}
return ans;
}
}
复杂度分析
- 时间复杂度:O(n),n 是 数组 nums 的长度。
- 空间复杂度:O(n)。