Start learning free

LESSON 233 OF 410 · PARTIAL SUMS #1

Longest Subarray with Sum at most S in O(n^2) Time Complexity using JavaScript

Practice O(n2) Read the full explanation

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

Note:

Your algorithm should run in O(n^2) time and use O(1) extra space.


STEP 1 OF 10
    Ctrl + Enter to check

    JAVASCRIPT · PARTIAL SUMS #1

    Longest Subarray With Sum At Most S in JavaScript, explained

    Problem Definition

    The problem requires finding the longest contiguous subarray within a given array of positive integers such that the sum of the subarray is at most a given number S. The output should be the start and end indices of this subarray.

    Input:

    • nums: An array of positive integers.
    • S: A positive integer representing the maximum allowed sum of the subarray.

    Output:

    • An array containing two integers representing the start and end indices of the longest subarray with sum at most S.

    Constraints:

    • The algorithm should run in O(n^2) time complexity.
    • The algorithm should use O(1) extra space.

    Example:

    Input: nums = [3, 2, 5, 2, 2, 1, 1, 3, 1, 2], S = 11
    Output: [3, 8]
    Explanation: The subarray nums[3...8] has a sum of 10, which is the longest subarray with sum at most 11.
    

    Understanding the Problem

    The core challenge is to find the longest contiguous subarray whose sum does not exceed a given value S. This problem is significant in scenarios where resource constraints are critical, such as memory usage in computing or budget constraints in financial planning.

    Potential pitfalls include misunderstanding the requirement for the subarray to be contiguous and not considering all possible subarrays.

    Approach

    To solve this problem, we can use a sliding window approach. The idea is to maintain a window that expands and contracts to find the longest subarray with a sum at most S.

    Naive Solution:

    A naive solution would involve checking all possible subarrays and calculating their sums, which would result in a time complexity of O(n^3). This is not optimal.

    Optimized Solution:

    We can improve the solution by using a sliding window technique:

    • Initialize two pointers, start and end, both set to the beginning of the array.
    • Expand the end pointer to include more elements in the window and keep track of the sum of the current window.
    • If the sum exceeds S, move the start pointer to reduce the window size until the sum is at most S.
    • Keep track of the maximum window size and the corresponding start and end indices.

    Algorithm

    Here is a step-by-step breakdown of the sliding window algorithm:

    1. Initialize start and end to 0, currentSum to 0, and maxLength to 0.
    2. Iterate through the array using the end pointer.
    3. Add the current element to currentSum.
    4. While currentSum exceeds S, increment the start pointer and subtract the element at start from currentSum.
    5. If the current window size is greater than maxLength, update maxLength and store the current start and end indices.
    6. Continue until the end of the array is reached.

    Code Implementation

    /**
     * Function to find the longest subarray with sum at most S
     * @param {number[]} nums - Array of positive integers
     * @param {number} S - Maximum allowed sum of the subarray
     * @return {number[]} - Start and end indices of the longest subarray
     */
    function longestSubarrayWithSumAtMostS(nums, S) {
        let start = 0;
        let currentSum = 0;
        let maxLength = 0;
        let result = [-1, -1];
    
        for (let end = 0; end < nums.length; end++) {
            // Add the current element to the current sum
            currentSum += nums[end];
    
            // While the current sum exceeds S, move the start pointer to the right
            while (currentSum > S) {
                currentSum -= nums[start];
                start++;
            }
    
            // Update the maximum length and result indices if a longer subarray is found
            if (end - start + 1 > maxLength) {
                maxLength = end - start + 1;
                result = [start, end];
            }
        }
    
        return result;
    }
    
    // Example usage:
    const nums = [3, 2, 5, 2, 2, 1, 1, 3, 1, 2];
    const S = 11;
    console.log(longestSubarrayWithSumAtMostS(nums, S)); // Output: [3, 8]
    

    Complexity Analysis

    The time complexity of the sliding window approach is O(n) because each element is processed at most twice (once when added and once when subtracted). The space complexity is O(1) as we are using a constant amount of extra space.

    Edge Cases

    Consider the following edge cases:

    • All elements are greater than S: The function should return an empty subarray or [-1, -1].
    • The array is empty: The function should return an empty subarray or [-1, -1].
    • S is very large: The function should return the entire array.

    Examples of Edge Cases:

    Input: nums = [12, 15, 20], S = 10
    Output: [-1, -1]
    
    Input: nums = [], S = 10
    Output: [-1, -1]
    
    Input: nums = [1, 2, 3, 4, 5], S = 100
    Output: [0, 4]
    

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Simple cases with small arrays.
    • Edge cases as discussed above.
    • Large arrays to test performance.

    Example Test Cases:

    console.log(longestSubarrayWithSumAtMostS([3, 2, 5, 2, 2, 1, 1, 3, 1, 2], 11)); // [3, 8]
    console.log(longestSubarrayWithSumAtMostS([12, 15, 20], 10)); // [-1, -1]
    console.log(longestSubarrayWithSumAtMostS([], 10)); // [-1, -1]
    console.log(longestSubarrayWithSumAtMostS([1, 2, 3, 4, 5], 100)); // [0, 4]
    

    Thinking and Problem-Solving Tips

    When approaching such problems, consider the following tips:

    • Understand the problem requirements and constraints thoroughly.
    • Think about different approaches and their trade-offs.
    • Start with a simple solution and then optimize it.
    • Use diagrams or pseudo-code to visualize the problem and solution.
    • Practice similar problems to improve problem-solving skills.

    Conclusion

    In this blog post, we discussed how to find the longest subarray with a sum at most S using a sliding window approach. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for improving problem-solving skills and preparing for coding interviews.

    Additional Resources

    For further reading and practice, consider the following resources:

    • LeetCode - A platform for practicing coding problems.
    • GeeksforGeeks - A website with tutorials and problems on various algorithms and data structures.
    • HackerRank - A platform for coding challenges and competitions.
    Keep going with JavaScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free