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 <= 109Problem Overview: You are given an integer array and a value k. A subarray is considered good if the absolute difference between its first and last elements equals k. The goal is to compute the maximum possible sum among all such subarrays.
Approach 1: Two Pointers with Prefix Sum Tracking (O(n) time, O(n) space)
This approach scans the array while maintaining running prefix sums so any subarray sum can be computed in constant time. While iterating with a right pointer, track previously seen values and check whether a value equal to nums[r] - k or nums[r] + k appeared earlier. If such a value exists, treat its position as a potential starting point and compute the subarray sum using prefix sums. Two moving boundaries help evaluate candidate subarrays as the array is traversed once. The method relies on fast lookups and incremental prefix updates, making it efficient for large arrays.
Approach 2: HashMap for Start Index Distribution (O(n) time, O(n) space)
The optimal solution combines prefix sum with a hash table. As you iterate through the array, maintain the current prefix sum and a map storing the minimum prefix sum observed before each value. For the current value x, check whether x - k or x + k has appeared before. If it has, subtract the stored minimum prefix sum from the current prefix to get the candidate subarray sum. Updating the map with the smallest prefix value ensures future subarrays produce the largest possible sum. This approach avoids storing all indices and keeps the lookup constant time, resulting in a clean linear solution using array traversal and hashing.
Recommended for interviews: Interviewers typically expect the hash map + prefix sum solution. A brute force idea demonstrates understanding of subarrays, but the optimized approach shows you know how to transform subarray sum problems into prefix computations with constant-time hash lookups.
In this approach, we start from each element and use two pointers to find good subarrays. One pointer begins at the current element and moves forward to find potential subarray ends. The other pointer helps to calculate the sum of the subarray.
This C code uses two pointers to go through every potential subarray that starts with an element in the array. If the difference between the first element and current pointed element is k, it calculates the subarray's sum and updates the maxSum accordingly.
Time Complexity: O(n^3).
Space Complexity: O(1).
This approach utilizes a HashMap to map the possible starting points of subarrays to see if the given element can serve as a potential endpoint to build a good subarray.
This C code uses a HashMap to store potential starting elements of a good subarray. For each element, it checks if the current element can be an endpoint for valid subarrays by checking in the HashMap.
Time Complexity: O(n^2).
Space Complexity: O(n) for the hash table storage.
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.
| Approach | Complexity |
|---|---|
| Two Pointers Approach | Time Complexity: O(n^3). |
| HashMap for Start Index Distribution | Time Complexity: O(n^2). |
| Prefix Sum + Hash Table | — |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Two Pointers with Prefix Sum | O(n) | O(n) | When scanning the array once while evaluating candidate boundaries using prefix sums |
| HashMap + Prefix Sum (Optimal) | O(n) | O(n) | General case; best choice when fast lookups for values differing by k are required |
3026. Maximum Good Subarray Sum | Prefix Sums | Hash Table | Biweekly Contest 123 • Aryan Mittal • 6,451 views views
Watch 9 more video solutions →Practice Maximum Good Subarray Sum with our built-in code editor and test cases.
Practice on FleetCode