Start learning free

LESSON 235 OF 410 · PARTIAL SUMS #2

Subarray of Given Sum II in O(n) Time Complexity using JavaScript

Practice O(n) Read the full explanation

Given an array of integers and a number target, find a continuous subarray whose sum is equal to target.

Return the start and end indices denoting this subarray, or -1 and -1 if there is none. If there are multiple solutions, you can return any of them.


Example:

Input: nums = [1, 1, 5, 2, 1, 3, 10, 2, 1], target = 21
Output: [2, 6]
Explanation: 5 + 2 + 1 + 3 + 10 = 21

Notes:

1. The array can consist of positive and negative numbers.

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


Video Solution - Live Mock Coding Interview:
STEP 1 OF 10
    Ctrl + Enter to check

    JAVASCRIPT · PARTIAL SUMS #2

    Subarray Of Given Sum in JavaScript, explained

    Problem Definition

    The problem requires finding a continuous subarray within a given array of integers that sums up to a specified target value. The solution should return the start and end indices of this subarray. If there are multiple solutions, any one of them can be returned.

    Input:

    • nums: An array of integers, which can include both positive and negative numbers.
    • target: An integer representing the target sum.

    Output:

    • An array containing two integers representing the start and end indices of the subarray whose sum equals the target.

    Constraints:

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

    Example:

    Input: nums = [1, 1, 5, 2, 1, 3, 10, 2, 1], target = 21
    Output: [2, 6]
    Explanation: 5 + 2 + 1 + 3 + 10 = 21

    Understanding the Problem

    The core challenge is to find a continuous subarray that sums up to the target value. This problem is significant in various applications such as financial analysis, where one might need to find a period with a specific sum of transactions.

    Potential pitfalls include handling negative numbers and ensuring the solution runs efficiently within the given constraints.

    Approach

    To solve this problem, we can use a sliding window approach combined with a hash map to keep track of the cumulative sums. This approach ensures that we can find the subarray in O(n) time complexity.

    Naive Solution

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

    Optimized Solution

    The optimized solution involves using a hash map to store the cumulative sum up to each index. By doing this, we can quickly check if there is a subarray that sums to the target by looking for the difference between the current cumulative sum and the target in the hash map.

    Algorithm

    Here is a step-by-step breakdown of the optimized algorithm:

    1. Initialize a hash map to store the cumulative sums and their corresponding indices.
    2. Initialize a variable to keep track of the cumulative sum.
    3. Iterate through the array, updating the cumulative sum at each step.
    4. Check if the cumulative sum equals the target. If so, return the indices from the start to the current index.
    5. Check if the difference between the cumulative sum and the target exists in the hash map. If so, return the indices from the next index of the stored index to the current index.
    6. Store the current cumulative sum and its index in the hash map.

    Code Implementation

    /**
     * Function to find the subarray with a given sum.
     * @param {number[]} nums - The array of integers.
     * @param {number} target - The target sum.
     * @return {number[]} - The start and end indices of the subarray.
     */
    function subarraySum(nums, target) {
        // Initialize a map to store cumulative sums and their indices
        const map = new Map();
        // Initialize the cumulative sum
        let cumulativeSum = 0;
        // Iterate through the array
        for (let i = 0; i < nums.length; i++) {
            // Update the cumulative sum
            cumulativeSum += nums[i];
            // Check if the cumulative sum equals the target
            if (cumulativeSum === target) {
                return [0, i];
            }
            // Check if the difference between cumulative sum and target exists in the map
            if (map.has(cumulativeSum - target)) {
                return [map.get(cumulativeSum - target) + 1, i];
            }
            // Store the cumulative sum and its index in the map
            map.set(cumulativeSum, i);
        }
        // Return an empty array if no subarray is found
        return [];
    }
    
    // Example usage
    const nums = [1, 1, 5, 2, 1, 3, 10, 2, 1];
    const target = 21;
    console.log(subarraySum(nums, target)); // Output: [2, 6]
    

    Complexity Analysis

    The time complexity of this approach is O(n) because we iterate through the array once. The space complexity is also O(n) due to the hash map storing the cumulative sums.

    Edge Cases

    Potential edge cases include:

    • An empty array: The function should return an empty array.
    • All negative numbers: The function should handle negative sums correctly.
    • Multiple subarrays with the same sum: The function can return any valid subarray.

    Testing

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

    • Simple cases with small arrays.
    • Cases with negative numbers.
    • Cases with multiple valid subarrays.
    • Edge cases such as empty arrays or arrays with a single element.

    Thinking and Problem-Solving Tips

    When approaching such problems, consider the following tips:

    • Break down the problem into smaller parts.
    • Think about different approaches and their time complexities.
    • Use hash maps or other data structures to optimize the solution.
    • Practice similar problems to improve problem-solving skills.

    Conclusion

    In this blog post, we discussed how to find a continuous subarray with a given sum in O(n) time complexity using JavaScript. 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:

    Keep going with JavaScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free