Given an array of positive integers and a number S, find the longest contiguous subarray having the sum at most S.
Return the start and end indices denoting this subarray.
Example
Input: nums = [3, 2, 5, 2, 2, 1, 1, 3, 1 , 2]
, S = 11
Output: [3, 8]
Explanation:the subarray nums[3...8] of sum 10
Your algorithm should run in O(n) time and use O(1) extra space.
The core challenge of this problem is to find the longest contiguous subarray whose sum does not exceed a given value S. This problem is significant in various applications such as resource allocation, budgeting, and data analysis where constraints on sums are common.
Potential pitfalls include misunderstanding the requirement for the subarray to be contiguous and not considering all possible subarrays.
To solve this problem, we can use a sliding window (or two-pointer) technique. This approach allows us to efficiently find the longest subarray with a sum at most S in O(n) time complexity.
Here’s a step-by-step breakdown of the approach:
start
and end
, both set to the beginning of the array.current_sum
to store the sum of the current subarray.end
pointer. Add the value at the end
pointer to current_sum
.current_sum
exceeds S, increment the start
pointer to reduce the sum until it is less than or equal to S.Here is the step-by-step algorithm:
start
, end
, current_sum
, max_length
, best_start
, and best_end
.end
pointer.current_sum
.current_sum
is greater than S, increment the start
pointer and subtract the value at start
from current_sum
.max_length
, update max_length
, best_start
, and best_end
.best_start
and best_end
.
#include <iostream>
#include <vector>
using namespace std;
pair longestSubarrayWithSumAtMostS(const vector<int>& nums, int S) {
int start = 0, end = 0, current_sum = 0;
int max_length = 0, best_start = 0, best_end = 0;
while (end < nums.size()) {
// Add the current element to the current_sum
current_sum += nums[end];
// While current_sum exceeds S, move the start pointer to the right
while (current_sum > S) {
current_sum -= nums[start];
start++;
}
// Update the maximum length and best indices if we found a longer subarray
if (end - start + 1 > max_length) {
max_length = end - start + 1;
best_start = start;
best_end = end;
}
// Move the end pointer to the right
end++;
}
return {best_start, best_end};
}
int main() {
vector<int> nums = {3, 2, 5, 2, 2, 1, 1, 3, 1, 2};
int S = 11;
pair<int, int> result = longestSubarrayWithSumAtMostS(nums, S);
cout << "Longest subarray with sum at most " << S << " is from index " << result.first << " to " << result.second << endl;
return 0;
}
The time complexity of this approach is O(n) because each element is processed at most twice (once by the end
pointer and once by the start
pointer). The space complexity is O(1) as we are using a constant amount of extra space.
Consider the following edge cases:
To test the solution comprehensively, consider the following test cases:
When approaching such problems, consider the following tips:
In this blog post, we discussed how to find the longest subarray with a sum at most S using a sliding window technique. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for improving algorithmic thinking and coding skills.
For further reading and practice, consider the following resources: