Subarray with a Given Sum (Positive Numbers)
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
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.
/*
* 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)
- Why does this fail with negative numbers?
- When do we move the left side?