3026. Maximum Good Subarray Sum
Description
You are given an array nums of length n and a positive integer k.
A subarray of nums is called good if the absolute difference between its first and last element is exactly k, in other words, the subarray nums[i..j] is good if |nums[i] - nums[j]| == k.
Return the maximum sum of a good subarray of nums. If there are no good subarrays, return 0.
Example 1:
Input: nums = [1,2,3,4,5,6], k = 1 Output: 11 Explanation: The absolute difference between the first and last element must be 1 for a good subarray. All the good subarrays are: [1,2], [2,3], [3,4], [4,5], and [5,6]. The maximum subarray sum is 11 for the subarray [5,6].
Example 2:
Input: nums = [-1,3,2,4,5], k = 3 Output: 11 Explanation: The absolute difference between the first and last element must be 3 for a good subarray. All the good subarrays are: [-1,3,2], and [2,4,5]. The maximum subarray sum is 11 for the subarray [2,4,5].
Example 3:
Input: nums = [-1,-2,-3,-4], k = 2 Output: -6 Explanation: The absolute difference between the first and last element must be 2 for a good subarray. All the good subarrays are: [-1,-2,-3], and [-2,-3,-4]. The maximum subarray sum is -6 for the subarray [-1,-2,-3].
Constraints:
2 <= nums.length <= 105-109 <= nums[i] <= 1091 <= k <= 109
Solutions
Solution 1: Prefix Sum + Hash Table
Thinking
A good subarray has endpoints differing by \(k\) in absolute value, and we want the maximum sum. \(n \le 10^5\) forbids enumerating ends.
The sum is a difference of prefix sums. For a right end \(x\) the left end is \(x-k\) or \(x+k\), and we want the smallest prefix at that value.
A hash map stores the minimum prefix (excluding the element itself). We update the answer from the current prefix, then offer that prefix to the next value.
We use a hash table \(p\) to record the sum \(s\) of the prefix array \(nums[0..i-1]\) for \(nums[i]\). If there are multiple identical \(nums[i]\), we only keep the smallest \(s\). Initially, we set \(p[nums[0]]\) to \(0\). In addition, we use a variable \(s\) to record the current prefix sum, initially \(s = 0\). Initialize the answer \(ans\) to \(-\infty\).
Next, we enumerate \(nums[i]\), and maintain a variable \(s\) to represent the sum of \(nums[0..i]\). If \(nums[i] - k\) is in \(p\), then we have found a good subarray, and update the answer to \(ans = \max(ans, s - p[nums[i] - k])\). Similarly, if \(nums[i] + k\) is in \(p\), then we have also found a good subarray, and update the answer to \(ans = \max(ans, s - p[nums[i] + k])\). Then, if \(i + 1 \lt n\) and \(nums[i + 1]\) is not in \(p\), or \(p[nums[i + 1]] \gt s\), we set \(p[nums[i + 1]]\) to \(s\).
Finally, if \(ans = -\infty\), then we return \(0\), otherwise return \(ans\).
The time complexity is \(O(n)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |