Subarray with a Given Sum (Positive Numbers)

medium Arrays

Problem

All numbers in the array are positive. Find the first continuous part (the one with the smallest start position) whose sum is exactly k. Print its 1-based start and end positions, separated by a space. If there is no such part, print -1.

Constraints

  • 1 <= n <= 10^5
  • 1 <= a[i] <= 10^4
  • 1 <= k <= 10^9

Examples

Input

5
1 2 3 7 5
12

Output

2 4

Solutions

Best approachTime O(n)Space O(1)

The window grows on the right and shrinks on the left. Because all numbers are positive, a bigger window always has a bigger sum, so each number enters and leaves the window once. O(n) time.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Subarray with sum k.
 * Input   : n, the array, then k.
 * Output  : Start and end or -1.
 * Approach: Sliding window.
 * Time    : O(n)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static String solve(int[] a, int k) {
        // Step 1: The window is a[left..right]. "sum" is the sum of the window.
        long sum = 0;
        int left = 0;
        for (int right = 0; right < a.length; right++) {
            sum += a[right];
            // Step 2: Too big: shrink the window from the left. All numbers are positive, so this only lowers the sum.
            while (sum > k && left <= right) {
                sum -= a[left++];
            }
            // Step 3: The first window that reaches exactly k is the answer.
            if (sum == k) {
                return (left + 1) + " " + (right + 1);
            }
        }
        return "-1";
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        int k = scanner.nextInt();
        System.out.println(solve(a, k));
    }
}
Hints (2)
  1. Why does this fail with negative numbers?
  2. When do we move the left side?