You are given an array of positive integers nums
and want to erase a subarray containing unique elements. The score you get by erasing the subarray is equal to the sum of its elements.
Return the maximum score you can get by erasing exactly one subarray.
An array b
is called to be a subarray of a
if it forms a contiguous subsequence of a
, that is, if it is equal to a[l],a[l+1],...,a[r]
for some (l,r)
.
Example 1:
Input: nums = [4,2,4,5,6] Output: 17 Explanation: The optimal subarray here is [2,4,5,6].
Example 2:
Input: nums = [5,2,1,2,5,2,1,2,5] Output: 8 Explanation: The optimal subarray here is [5,2,1] or [1,2,5].
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 104
Given an array of positive integers nums
, find the maximum sum of a subarray containing only unique elements. The subarray must be contiguous.
This approach uses a sliding window and a hash table to efficiently track unique elements within the window.
Initialization:
left
: Pointer indicating the start of the sliding window (initially 0).right
: Pointer indicating the end of the sliding window (initially 0).sum
: Current sum of elements within the window (initially 0).maxSum
: Maximum sum encountered so far (initially 0).window
: A hash table (dictionary in Python) to store elements within the window and their indices.Sliding Window:
right
to the right.nums[right]
is not in window
, add it to window
, update sum
, and update maxSum
.nums[right]
is already in window
, it means we have a duplicate. We need to shrink the window from the left until the duplicate is removed.
nums[right]
is in window
, remove nums[left]
from window
, update sum
, and increment left
.Return: maxSum
nums
. Each element is added and removed from the window at most once.window
hash table.def maximumUniqueSubarray(nums):
left = 0
right = 0
sum = 0
maxSum = 0
window = {} # Hash table to store elements and their indices
while right < len(nums):
if nums[right] not in window:
window[nums[right]] = right
sum += nums[right]
maxSum = max(maxSum, sum)
right += 1
else:
left_index = window[nums[right]]
while left <= left_index:
del window[nums[left]]
sum -= nums[left]
left += 1
return maxSum
This approach uses a prefix sum array and a hash table to efficiently calculate subarray sums. It's functionally equivalent to Approach 1 but might be slightly less intuitive.
Prefix Sum: Calculate the prefix sum array prefixSum
, where prefixSum[i]
is the sum of nums[0]
to nums[i-1]
.
Sliding Window (Implicit): Iterate through nums
. For each element nums[i]
, check its last occurrence using a hash table. If a duplicate is found within the current window (defined by the last occurrence index), adjust the window accordingly.
Return: The maximum sum found.
from itertools import accumulate
def maximumUniqueSubarray(nums):
prefixSum = list(accumulate(nums, initial=0)) #efficient way to calculate prefix sum using itertools
d = {} #Hash table to store last occurence
j = 0
ans = 0
for i, v in enumerate(nums):
if v in d:
j = max(j, d[v] + 1) #if there is a duplicate, then update the starting point of subarray
ans = max(ans, prefixSum[i+1] - prefixSum[j]) #find the sum of current subarray
d[v] = i # update last occurence of current element
return ans
Both approaches have the same time and space complexity. Choose the one you find more readable and easier to understand. The sliding window approach (Approach 1) is often considered more intuitive for this type of problem.