Start learning free

LESSON 235 OF 410 · PARTIAL SUMS #2

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

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

    JAVA · PARTIAL SUMS #2

    Subarray Of Given Sum in Java, 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:

    • An array of integers nums
    • An integer target

    Output:

    • An array containing two integers representing the start and end indices of the subarray.

    Constraints:

    • The array can contain both positive and negative numbers.
    • The algorithm should run in O(n) time and use O(n) extra space.

    Example:

    Input: nums = [1, 1, 5, 2, 1, 3, 10, 2, 1], k = 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 hashmap to store the cumulative sum at each index. This allows us to efficiently check if there is a subarray that sums to the target value.

    Naive Solution

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

    Optimized Solution

    We can optimize the solution using a hashmap to store the cumulative sum at each index. The idea is to keep track of the cumulative sum and check if the difference between the current cumulative sum and the target has been seen before.

    Algorithm

    1. Initialize a hashmap to store the cumulative sum and its corresponding index.

    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. If the difference between the cumulative sum and the target has been seen before, return the indices from the next index of the previously seen cumulative sum to the current index.

    6. Store the cumulative sum and its index in the hashmap.

    Code Implementation

    import java.util.HashMap;
    
    public class SubarraySum {
        public static int[] subarraySum(int[] nums, int target) {
            // HashMap to store the cumulative sum and its index
            HashMap<Integer, Integer> map = new HashMap<>();
            // Initialize the cumulative sum
            int cumulativeSum = 0;
            // Iterate through the array
            for (int 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 new int[]{0, i};
                }
                // Check if the difference between cumulative sum and target has been seen before
                if (map.containsKey(cumulativeSum - target)) {
                    return new int[]{map.get(cumulativeSum - target) + 1, i};
                }
                // Store the cumulative sum and its index in the map
                map.put(cumulativeSum, i);
            }
            // Return an empty array if no subarray is found
            return new int[]{};
        }
    
        public static void main(String[] args) {
            int[] nums = {1, 1, 5, 2, 1, 3, 10, 2, 1};
            int target = 21;
            int[] result = subarraySum(nums, target);
            if (result.length == 2) {
                System.out.println("Subarray found from index " + result[0] + " to " + result[1]);
            } else {
                System.out.println("No subarray found");
            }
        }
    }
    

    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 hashmap storing the cumulative sums.

    Edge Cases

    Potential edge cases include:

    • An empty array: The function should return an empty array.
    • An array with all negative numbers: The function should handle this correctly.
    • Multiple subarrays summing to the target: The function can return any one of them.

    Testing

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

    • Simple cases with small arrays.
    • Cases with negative numbers.
    • Edge cases like empty arrays or arrays with a single element.

    Thinking and Problem-Solving Tips

    When approaching such problems, it's essential to:

    • Understand the problem requirements and constraints thoroughly.
    • Think about potential edge cases and how to handle them.
    • Consider different approaches and their trade-offs.
    • Practice similar problems to improve problem-solving skills.

    Conclusion

    In this blog post, we discussed how to find a continuous subarray that sums up to a given target value. We explored a naive solution and an optimized solution using a hashmap. We also analyzed the complexity and discussed edge cases and testing strategies. Understanding and solving such problems is crucial for improving algorithmic thinking and problem-solving skills.

    Additional Resources

    For further reading and practice, consider the following resources:

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