Smallest subarray with sum greater than or equal to K (original) (raw)
Last Updated : 15 Jul, 2025
Given an array **A[] consisting of **N integers and an integer **K, the task is to find the length of the smallest subarray with sum greater than or equal to **K. If no such subarray exists, print **-1.
**Examples:
**Input: A[] = {2, -1, 2}, K = 3
**Output: 3
**Explanation:
Sum of the given array is 3.
Hence, the smallest possible subarray satisfying the required condition is the entire array.
Therefore, the length is 3.**Input: A[] = {2, 1, 1, -4, 3, 1, -1, 2}, K = 5
**Output: 4
**Naive Approach:
The simplest approach to solve the problem is to generate all possible subarrays of the given array and check which subarray sum is greater than or equal to **K. Among all such subarrays satisfying the condition, print the subarray having minimum length.
Below is the implementation of the above idea:
C++ `
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the smallest subarray // with sum greater than or equal to K int findSubarray(int arr[], int n, int k) { //For storing minimum length of those subarray that // have sum greater than or equal to K int ans=INT_MAX;
for(int i=0;i<n;i++){ //For sum of all elements of subarray int sum=0; //For length of subarray int count=0; for(int j=i;j<n;j++){ count++; sum+=arr[j]; if(sum>=k){ if(count<ans){ans=count;} } } }
//When no such subarray exists if(ans==INT_MAX){return -1;}
return ans; }
// Driver Code int main() { int arr[] = { 2, 1, 1, -4, 3, 1, -1, 2 }; int k = 5; int n = sizeof(arr) / sizeof(arr[0]); cout << findSubarray(arr, n, k) << endl; return 0; }
Java
// Java Program to implement // the above approach import java.util.*;
class GFG {
// Function to find the smallest subarray
// with sum greater than or equal to K
static int findSubarray(int[] arr, int n, int k)
{
// For storing minimum length of those subarray that
// have sum greater than or equal to K
int ans = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
// For sum of all elements of subarray
int sum = 0;
// For length of subarray
int count = 0;
for (int j = i; j < n; j++) {
count++;
sum += arr[j];
if (sum >= k) {
if (count < ans) {
ans = count;
}
}
}
}
// When no such subarray exists
if (ans == Integer.MAX_VALUE) {
return -1;
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int[] arr = { 2, 1, 1, -4, 3, 1, -1, 2 };
int k = 5;
int n = arr.length;
System.out.println(findSubarray(arr, n, k));
}} // This code is contributed by prasad264
Python3
Python program to implement
the above approach
Function to find the smallest subarray
with sum greater than or equal to K
def findSubarray(arr, n, k): # For storing minimum length of those subarray that # have sum greater than or equal to K ans = float('inf')
for i in range(n):
# For sum of all elements of subarray
sum = 0
# For length of subarray
count = 0
for j in range(i, n):
count += 1
sum += arr[j]
if sum >= k:
if count < ans:
ans = count
# When no such subarray exists
if ans == float('inf'):
return -1
return ansDriver Code
arr = [2, 1, 1, -4, 3, 1, -1, 2] k = 5 n = len(arr) print(findSubarray(arr, n, k))
C#
using System;
class Program { // Function to find the smallest subarray with sum greater than or equal to K static int FindSubarray(int[] arr, int n, int k) { // For storing the minimum length of those subarrays // that have a sum greater than or equal to K int ans = int.MaxValue;
for (int i = 0; i < n; i++)
{
// For the sum of all elements of the subarray
int sum = 0;
// For the length of the subarray
int count = 0;
for (int j = i; j < n; j++)
{
count++;
sum += arr[j];
if (sum >= k)
{
if (count < ans)
{
ans = count;
}
}
}
}
// When no such subarray exists
if (ans == int.MaxValue)
{
return -1;
}
return ans;
}
// Driver Code
static void Main(string[] args)
{
int[] arr = { 2, 1, 1, -4, 3, 1, -1, 2 };
int k = 5;
int n = arr.Length;
Console.WriteLine(FindSubarray(arr, n, k));
}}
JavaScript
// Function to find the smallest subarray // with sum greater than or equal to K function findSubarray(arr, k) { // For storing minimum length of those subarrays // that have sum greater than or equal to K let ans = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < arr.length; i++) {
// For sum of all elements of subarray
let sum = 0;
// For length of subarray
let count = 0;
for (let j = i; j < arr.length; j++) {
count++;
sum += arr[j];
if (sum >= k) {
if (count < ans) {
ans = count;
}
}
}
}
// When no such subarray exists
if (ans === Number.MAX_SAFE_INTEGER) {
return -1;
}
return ans;}
// Driver Code const arr = [2, 1, 1, -4, 3, 1, -1, 2]; const k = 5; console.log(findSubarray(arr, k));
`
****Time Complexity:**O(N2)
**Auxiliary Space: O(1)
**Smallest subarray with sum greater than or equal to K using Prefix Sum Array and Binary search:
Follow the steps below:
- Initialize an array to store the **Prefix sum of the original array.
- Hash the prefix sum array with the indices using a Map.
- If a _greater sum with a lesser index is already found, then there is no point of hashing a prefix sum which is smaller than the largest prefix sum obtained till now. Therefore, hash the _increasing order of prefix sum.
- Traversing the array and if any element is greater than or equal to **K, return 1 as the answer.
- Otherwise, for every element, perform **Binary Search over the indices ****(i, n-1)** in the **prefix sum array to find the first index with sum at least K.
- Return the minimum length subarray obtained from the above steps.
Below is the implementation of the above approach:
C++ `
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Function to perform Binary Search // and return the smallest index with // sum greater than value int binary_search(map<int, vector >& m, int value, int index) { // Search the value in map auto it = m.lower_bound(value);
// If all keys in the map
// are less than value
if (it == m.end())
return 0;
// Check if the sum is found
// at a greater index
auto it1
= lower_bound(it->second.begin(),
it->second.end(), index);
if ((it1 - it->second.begin())
!= it->second.size())
return *it1;
return 0;}
// Function to find the smallest subarray // with sum greater than equal to K int findSubarray(int arr[], int n, int k) {
// Prefix sum array
int pre_array[n];
// Stores the hashes to prefix sum
map<int, vector<int> > m;
pre_array[0] = arr[0];
m[pre_array[0]].push_back(0);
// If any array element is
// greater than equal to k
if (arr[0] >= k)
return 1;
int ans = INT_MAX;
for (int i = 1; i < n; i++) {
pre_array[i]
= arr[i] + pre_array[i - 1];
// If prefix sum exceeds K
if (pre_array[i] >= k)
// Update size of subarray
ans = min(ans, i + 1);
auto it = m.rbegin();
// Hash prefix sum in
// increasing order
if (pre_array[i] >= it->first)
m[pre_array[i]].push_back(i);
}
for (int i = 1; i < n; i++) {
int temp
= binary_search(m,
pre_array[i - 1] + k,
i);
if (temp == 0)
continue;
// Update size of subarray
ans = min(ans, temp - i + 1);
}
// If any subarray is found
if (ans <= n)
return ans;
// If no such subarray exists
return -1;}
// Driver Code int main() { int arr[] = { 2, 1, 1, -4, 3, 1, -1, 2 };
int k = 5;
int n = sizeof(arr) / sizeof(arr[0]);
cout << findSubarray(arr, n, k) << endl;
return 0;}
Java
import java.util.*;
public class Main {
// Function to perform Binary Search // and return the smallest index with // sum greater than value public static int binary_search(TreeMap<Integer, ArrayList> m, int value, int index) { // Search the value in map Map.Entry<Integer, ArrayList> it = m.ceilingEntry(value);
// If all keys in the map
// are less than value
if (it == null)
return 0;
// Check if the sum is found
// at a greater index
ArrayList<Integer> list = it.getValue();
int i = Collections.binarySearch(list, index);
if (i >= 0)
return list.get(i);
return -i-1 < list.size() ? list.get(-i-1) : 0;}
// Function to find the smallest subarray // with sum greater than equal to K public static int findSubarray(int[] arr, int n, int k) {
// Prefix sum array
int[] pre_array = new int[n];
// Stores the hashes to prefix sum
TreeMap<Integer, ArrayList<Integer>> m = new TreeMap<>();
pre_array[0] = arr[0];
ArrayList<Integer> l = new ArrayList<>();
l.add(0);
m.put(pre_array[0], l);
// If any array element is
// greater than equal to k
if (arr[0] >= k)
return 1;
int ans = Integer.MAX_VALUE;
for (int i = 1; i < n; i++) {
pre_array[i]
= arr[i] + pre_array[i - 1];
// If prefix sum exceeds K
if (pre_array[i] >= k)
// Update size of subarray
ans = Math.min(ans, i + 1);
Map.Entry<Integer, ArrayList<Integer>> it = m.lastEntry();
// Hash prefix sum in
// increasing order
if (pre_array[i] >= it.getKey())
m.computeIfAbsent(pre_array[i], k1 -> new ArrayList<>()).add(i);
}
for (int i = 1; i < n; i++) {
int temp
= binary_search(m,
pre_array[i - 1] + k,
i);
if (temp == 0)
continue;
// Update size of subarray
ans = Math.min(ans, temp - i + 1);
}
// If any subarray is found
if (ans <= n)
return ans;
// If no such subarray exists
return -1;}
// Driver Code public static void main(String[] args) { int[] arr = { 2, 1, 1, -4, 3, 1, -1, 2 };
int k = 5;
int n = arr.length;
System.out.println(findSubarray(arr, n, k));} }
Python3
import bisect
Function to perform Binary Search
and return the smallest index with
sum greater than value
def binary_search(m, value, index): # Get the keys of the dictionary in sorted order keys = sorted(m.keys())
# If all keys in the dictionary are less than value
if keys[-1] < value:
return 0
# Search for the first key that is greater than or equal to value
key = keys[bisect.bisect_left(keys, value)]
# Check if the sum is found at a greater index
if m[key][-1] >= index:
# Search for the first index in the list that is greater than or equal to index
return m[key][bisect.bisect_left(m[key], index)]
return 0Function to find the smallest subarray
with sum greater than equal to K
def findSubarray(arr, n, k): # Prefix sum array pre_array = [0] * n
# Stores the hashes to prefix sum
m = {}
pre_array[0] = arr[0]
m[pre_array[0]] = [0]
# If any array element is greater than or equal to k
if arr[0] >= k:
return 1
ans = float('inf')
for i in range(1, n):
pre_array[i] = arr[i] + pre_array[i - 1]
# If prefix sum exceeds K
if pre_array[i] >= k:
# Update size of subarray
ans = min(ans, i + 1)
# Hash prefix sum in increasing order
if pre_array[i] in m:
m[pre_array[i]].append(i)
else:
m[pre_array[i]] = [i]
for i in range(1, n):
temp = binary_search(m, pre_array[i - 1] + k, i)
if temp == 0:
continue
# Update size of subarray
ans = min(ans, temp - i + 1)
# If any subarray is found
if ans <= n:
return ans
# If no such subarray exists
return -1Driver Code
arr = [2, 1, 1, -4, 3, 1, -1, 2] k = 5 n = len(arr)
print(findSubarray(arr, n, k))
C#
//C# code using System; using System.Collections.Generic; using System.Linq;
namespace MainProgram { class MainClass { // Function to perform Binary Search // and return the smallest index with // sum greater than value public static int binary_search(SortedDictionary<int, List> m, int value, int index) { // Search the value in map KeyValuePair<int, List> it = m.FirstOrDefault(x => x.Key >= value);
// If all keys in the map
// are less than value
if (it.Equals(default(KeyValuePair<int, List<int>>)))
return 0;
// Check if the sum is found
// at a greater index
List<int> list = it.Value;
int i = list.BinarySearch(index);
if (i >= 0)
return list[i];
return -i - 1 < list.Count ? list[-i - 1] : 0;
}
// Function to find the smallest subarray
// with sum greater than equal to K
public static int findSubarray(int[] arr, int n, int k)
{
// Prefix sum array
int[] pre_array = new int[n];
// Stores the hashes to prefix sum
SortedDictionary<int, List<int>> m = new SortedDictionary<int, List<int>>();
pre_array[0] = arr[0];
List<int> l = new List<int>();
l.Add(0);
m.Add(pre_array[0], l);
// If any array element is
// greater than equal to k
if (arr[0] >= k)
return 1;
int ans = Int32.MaxValue;
for (int i = 1; i < n; i++)
{
pre_array[i]
= arr[i] + pre_array[i - 1];
// If prefix sum exceeds K
if (pre_array[i] >= k)
// Update size of subarray
ans = Math.Min(ans, i + 1);
KeyValuePair<int, List<int>> it = m.Last();
// Hash prefix sum in
// increasing order
if (pre_array[i] >= it.Key)
{
if (m.ContainsKey(pre_array[i]))
{
m[pre_array[i]].Add(i);
}
else
{
m.Add(pre_array[i], new List<int> { i });
}
}
}
for (int i = 1; i < n; i++)
{
int temp
= binary_search(m,
pre_array[i - 1] + k,
i);
if (temp == 0)
continue;
// Update size of subarray
ans = Math.Min(ans, temp - i + 1);
}
// If any subarray is found
if (ans <= n)
return ans;
// If no such subarray exists
return -1;
}
// Driver Code
public static void Main(string[] args)
{
int[] arr = { 2, 1, 1, -4, 3, 1, -1, 2 };
int k = 5;
int n = arr.Length;
Console.WriteLine(findSubarray(arr, n, k));
}
}}
JavaScript
// Function to perform Binary Search // and return the smallest index with // sum greater than value function binary_search(m, value, index) { // Search the value in map let it = Array.from(m).find(([k]) => k >= value);
// If all keys in the map // are less than value if (it == undefined) return 0;
// Check if the sum is found // at a greater index let it1 = it[1].find((val) => val >= index);
if (it1 != undefined) return it1;
return 0; }
// Function to find the smallest subarray // with sum greater than equal to K function findSubarray(arr, n, k) { // Prefix sum array let pre_array = new Array(n);
// Stores the hashes to prefix sum let m = new Map();
pre_array[0] = arr[0]; m.set(pre_array[0], [0]);
// If any array element is // greater than equal to k if (arr[0] >= k) return 1;
let ans = Number.MAX_SAFE_INTEGER; for (let i = 1; i < n; i++) { pre_array[i] = arr[i] + pre_array[i - 1];
// If prefix sum exceeds K if (pre_array[i] >= k) ans = Math.min(ans, i + 1);
let it = Array.from(m).reverse()[0];
// Hash prefix sum in // increasing order if (pre_array[i] >= it[0]) { let arr = m.get(pre_array[i]); if (arr == undefined) { arr = []; m.set(pre_array[i], arr); } arr.push(i); } }
for (let i = 1; i < n; i++) { let temp = binary_search(m, pre_array[i - 1] + k, i); if (temp == 0) continue;
// Update size of subarray ans = Math.min(ans, temp - i + 1); }
// If any subarray is found if (ans <= n) return ans;
// If no such subarray exists return -1; }
// Driver Code let arr = [2, 1, 1, -4, 3, 1, -1, 2];
let k = 5;
let n = arr.length;
console.log(findSubarray(arr, n, k));
`
**Time Complexity: O(NlogN)
**Auxiliary Space: O(N)
Smallest subarray with sum greater than or equal to K using Sliding Window:
The problem can be solved by maintaining a **deque storing the possible values of **start pointer in the array. Let's say we are at index **i, with prefix sum **P i so if we have two indices **j and **k, such that **k < j < i with prefix sums **P jand **P k , then we can say that it is always better to choose jover **k as the starting point provided **P j < P k because if we choose k as the starting point, the subarray sum would be ****(P** i -P k ) with subarray length as ****(i - k)** and if we take j as the starting point, the subarray sum would be ****(P** i -P j ) with subarray length as ****(i - j)**, which is better as the subarray sum is greater and the subarray length is smaller. So, we'll be iterating from 0 to the size of array, storing the deque in **increasing order of **prefix sums and calculating the **minimum length of subarray with sum greater than **K.
Steps to solve the problem:
- Calculate the prefix sums of the array **A[] as **prefSum[].
- Initialize an empty deque **dq.
- Iterate through the prefix sums array **prefSum.
- If the current prefix sum is greater than or equal to **K, update the minimum answer **ans.
- While **dq is not empty and the **difference between the current prefix sum and the prefix sum at the front of **dq is **greater than or equal to **K, update the minimum answer ans and pop the front element from **dq.
- While **dq is not empty and the prefix sum at the back of **dq is greater than or equal to the current prefix sum, pop the back element from **dq.
- Push the current index **i into **dq.
- Return the minimum answer **ans, or **-1 if no such answer exists.
Below is the implementation of the above approach:
C++ `
#include <bits/stdc++.h> using namespace std;
int getShortestSubarray(vector& A, int X) { int ans = INT_MAX, n = A.size(); // vector to store prefix sums vector prefSum(n); // deque storing index of increasing order prefix sums deque dq;
for (int i = 0; i < n; i++) {
prefSum[i] = A[i] + (i == 0 ? 0 : prefSum[i - 1]);
if (prefSum[i] >= X)
ans = min(ans, i + 1);
}
for (int i = 0; i < n; i++) {
// Check if the subarray ending at i has sum atleast
// X
while (!dq.empty()
&& prefSum[i] - prefSum[dq.front()] >= X) {
ans = min(ans, i - dq.front());
dq.pop_front();
}
// Make the deque store prefix sums in increasing
// order
while (!dq.empty()
&& prefSum[dq.back()] >= prefSum[i])
dq.pop_back();
dq.push_back(i);
}
return ans == INT_MAX ? -1 : ans;}
int main() { int N = 5; vector A{ 10, 20, -25, 5, 35 }; int X = 40; cout << getShortestSubarray(A, X); return 0; }
Java
import java.util.ArrayDeque; import java.util.Deque;
public class ShortestSubarray {
// Function to find the length of the shortest subarray with sum >= X
static int getShortestSubarray(int[] A, int X) {
int ans = Integer.MAX_VALUE; // Initializing the answer with the maximum value
int n = A.length; // Getting the length of the array
long[] prefSum = new long[n]; // Array to store prefix sums
Deque<Integer> dq = new ArrayDeque<>(); // Deque to store indices
// Calculating prefix sums
for (int i = 0; i < n; i++) {
prefSum[i] = A[i] + (i == 0 ? 0 : prefSum[i - 1]);
if (prefSum[i] >= X)
ans = Math.min(ans, i + 1); // Updating the answer if the prefix sum is already >= X
}
// Looping through the array to find the shortest subarray with sum >= X
for (int i = 0; i < n; i++) {
// Removing elements from the front of the deque if the current prefix sum - prefix sum at front >= X
while (!dq.isEmpty() && prefSum[i] - prefSum[dq.getFirst()] >= X) {
ans = Math.min(ans, i - dq.getFirst()); // Updating the answer
dq.removeFirst(); // Removing the index from the front
}
// Removing elements from the back of the deque if the prefix sum at back >= current prefix sum
while (!dq.isEmpty() && prefSum[dq.getLast()] >= prefSum[i])
dq.removeLast(); // Removing the index from the back
dq.addLast(i); // Adding the current index to the deque
}
// If ans is still the initialized maximum value, return -1, else return the length of the shortest subarray
return ans == Integer.MAX_VALUE ? -1 : ans;
}
public static void main(String[] args) {
int[] A = {10, 20, -25, 5, 35}; // Input array
int X = 40; // Target sum
System.out.println(getShortestSubarray(A, X)); // Printing the result of the function call
}}
Python3
Python Code
from collections import deque
Function to find the length of the shortest subarray with sum >= X
def get_shortest_subarray(A, X): ans = float('inf') # Initializing the answer with positive infinity n = len(A) # Getting the length of the array pref_sum = [0] * n # List to store prefix sums dq = deque() # Deque to store indices
# Calculating prefix sums
for i in range(n):
pref_sum[i] = A[i] + (pref_sum[i - 1] if i > 0 else 0)
if pref_sum[i] >= X:
ans = min(ans, i + 1) # Updating the answer if the prefix sum is already >= X
# Looping through the array to find the shortest subarray with sum >= X
for i in range(n):
# Removing elements from the front of the deque if the current prefix sum - prefix sum at front >= X
while dq and pref_sum[i] - pref_sum[dq[0]] >= X:
ans = min(ans, i - dq.popleft()) # Updating the answer
# Removing elements from the back of the deque if the prefix sum at back >= current prefix sum
while dq and pref_sum[dq[-1]] >= pref_sum[i]:
dq.pop() # Removing the index from the back
dq.append(i) # Adding the current index to the deque
# If ans is still positive infinity, return -1, else return the length of the shortest subarray
return -1 if ans == float('inf') else ansTest values
A = [10, 20, -25, 5, 35] # Input array X = 40 # Target sum print(get_shortest_subarray(A, X)) # Printing the result of the function call
This code is contributed by guptapratik
C#
using System; using System.Collections.Generic;
class Program { static int GetShortestSubarray(List A, int X) { int ans = int.MaxValue; int n = A.Count; // List to store prefix sums List prefSum = new List(n); // Deque storing index of increasing order prefix sums Queue dq = new Queue();
for (int i = 0; i < n; i++)
{
prefSum.Add(A[i] + (i == 0 ? 0 : prefSum[i - 1]));
if (prefSum[i] >= X)
ans = Math.Min(ans, i + 1);
}
for (int i = 0; i < n; i++)
{
// Check if the subarray ending at i has sum at least X
while (dq.Count > 0 && prefSum[i] - prefSum[dq.Peek()] >= X)
{
ans = Math.Min(ans, i - dq.Dequeue());
}
// Make the deque store prefix sums in increasing order
while (dq.Count > 0 && prefSum[dq.Peek()] >= prefSum[i])
{
dq.Dequeue();
}
dq.Enqueue(i);
}
return ans == int.MaxValue ? -1 : ans;
}
static void Main()
{
List<int> A = new List<int> { 10, 20, -25, 5, 35 };
int X = 40;
Console.WriteLine(GetShortestSubarray(A, X));
}}
JavaScript
function getShortestSubarray(A, X) { let ans = Infinity; const n = A.length; // Array to store prefix sums const prefSum = new Array(n).fill(0); // Deque storing index of increasing order prefix sums const dq = [];
for (let i = 0; i < n; i++) {
prefSum[i] = A[i] + (i === 0 ? 0 : prefSum[i - 1]);
if (prefSum[i] >= X) {
ans = Math.min(ans, i + 1);
}
}
for (let i = 0; i < n; i++) {
// Check if the subarray ending at i has sum at least X
while (dq.length > 0 && prefSum[i] - prefSum[dq[0]] >= X) {
ans = Math.min(ans, i - dq[0]);
dq.shift();
}
// Make the deque store prefix sums in increasing order
while (dq.length > 0 && prefSum[dq[dq.length - 1]] >= prefSum[i]) {
dq.pop();
}
dq.push(i);
}
return ans === Infinity ? -1 : ans;}
const N = 5; const A = [10, 20, -25, 5, 35]; const X = 40; console.log(getShortestSubarray(A, X));
`
**Time Complexity: O(N), where N is the size of input array A[].
**Auxiliary Space: O(N)