Smallest subarray from a given Array with sum greater than or equal to K | Set 2
Given an array A[] consisting of N positive integers and an integer K, the task is to find the length of the smallest subarray with a sum greater than or equal to K. If no such subarray exists, print -1.
Examples:
Input: arr[] = {3, 1, 7, 1, 2}, K = 11
Output: 3
Explanation:
The smallest subarray with sum ? K(= 11) is {3, 1, 7}.
Input: arr[] = {2, 3, 5, 4, 1}, K = 11
Output: 3
Explanation:
The minimum possible subarray is {3, 5, 4}.
Naive and Binary Search Approach: Refer to Smallest subarray from a given Array with sum greater than or equal to K for the simplest approach and the Binary Search based approaches to solve the problem.
Recursive Approach: The simplest approach to solve the problem is to use Recursion. Follow the steps below to solve the problem:
- If K ? 0: Print -1 as no such subarray can be obtained.
- If the sum of the array is equal to K, print the length of the array as the required answer.
- If the first element in the array is greater than K, then print 1 as the required answer.
- Otherwise, proceed to find the smallest subarray both by considering the current element in the subarray as well as not including it.
- Repeat the above steps for every element traversed.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
int smallSumSubset(vector< int > data,
int target, int maxVal)
{
int sum = 0;
for ( int i : data)
sum += i;
if (target <= 0)
return 0;
else if (sum < target)
return maxVal;
else if (sum == target)
return data.size();
else if (data[0] >= target)
return 1;
else if (data[0] < target)
{
vector< int > temp;
for ( int i = 1; i < data.size(); i++)
temp.push_back(data[i]);
return min(smallSumSubset(temp, target,
maxVal),
1 + smallSumSubset(temp, target -
data[0], maxVal));
}
}
int main()
{
vector< int > data = { 3, 1, 7, 1, 2 };
int target = 11;
int val = smallSumSubset(data, target,
data.size() + 1);
if (val > data.size())
cout << -1;
else
cout << val;
}
|
Java
import java.util.*;
import java.lang.*;
class GFG{
static int smallSumSubset(List<Integer> data,
int target, int maxVal)
{
int sum = 0 ;
for (Integer i : data)
sum += i;
if (target <= 0 )
return 0 ;
else if (sum < target)
return maxVal;
else if (sum == target)
return data.size();
else if (data.get( 0 ) >= target)
return 1 ;
else if (data.get( 0 ) < target)
{
List<Integer> temp = new ArrayList<>();
for ( int i = 1 ; i < data.size(); i++)
temp.add(data.get(i));
return Math.min(smallSumSubset(temp, target,
maxVal),
1 + smallSumSubset(temp, target -
data.get( 0 ), maxVal));
}
return - 1 ;
}
public static void main (String[] args)
{
List<Integer> data = Arrays.asList( 3 , 1 , 7 , 1 , 2 );
int target = 11 ;
int val = smallSumSubset(data, target,
data.size() + 1 );
if (val > data.size())
System.out.println(- 1 );
else
System.out.println(val);
}
}
|
Python3
def smallSumSubset(data, target, maxVal):
if target < = 0 :
return 0
elif sum (data) < target:
return maxVal
elif sum (data) = = target:
return len (data)
elif data[ 0 ] > = target:
return 1
elif data[ 0 ] < target:
return min (smallSumSubset(data[ 1 :], \
target, maxVal),
1 + smallSumSubset(data[ 1 :], \
target - data[ 0 ], maxVal))
data = [ 3 , 1 , 7 , 1 , 2 ]
target = 11
val = smallSumSubset(data, target, len (data) + 1 )
if val > len (data):
print ( - 1 )
else :
print (val)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int smallSumSubset(List< int > data,
int target, int maxVal)
{
int sum = 0;
foreach ( int i in data)
sum += i;
if (target <= 0)
return 0;
else if (sum < target)
return maxVal;
else if (sum == target)
return data.Count;
else if (data[0] >= target)
return 1;
else if (data[0] < target)
{
List< int > temp = new List< int >();
for ( int i = 1; i < data.Count; i++)
temp.Add(data[i]);
return Math.Min(smallSumSubset(temp, target,
maxVal),
1 + smallSumSubset(temp, target -
data[0], maxVal));
}
return 0;
}
static void Main()
{
List< int > data = new List< int >();
data.Add(3);
data.Add(1);
data.Add(7);
data.Add(1);
data.Add(2);
int target = 11;
int val = smallSumSubset(data, target,
data.Count + 1);
if (val > data.Count)
Console.Write(-1);
else
Console.Write(val);
}
}
|
Javascript
<script>
function smallSumSubset(data, target, maxVal)
{
let sum = 0;
for (let i=0;i< data.length;i++)
sum += data[i];
if (target <= 0)
return 0;
else if (sum < target)
return maxVal;
else if (sum == target)
return data.length;
else if (data[0] >= target)
return 1;
else if (data[0] < target)
{
let temp = [];
for (let i = 1; i < data.length; i++)
temp.push(data[i]);
return Math.min(smallSumSubset(temp, target,
maxVal),
1 + smallSumSubset(temp, target -
data[0], maxVal));
}
}
let data = [ 3, 1, 7, 1, 2 ];
let target = 11;
let val = smallSumSubset(data, target,
data.length + 1);
if (val > data.length)
document.write( -1);
else
document.write(val);
</script>
|
Time Complexity: O(2N)
Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized using Dynamic programming by memorizing the subproblems to avoid re-computation.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int minlt(vector< int > arr, int target, int n)
{
vector<vector< int >> dp(arr.size() + 1 ,
vector< int > (target + 1, -1));
for ( int i = 0; i < arr.size() + 1; i++)
dp[i][0] = 0;
for ( int j = 0; j < target + 1; j++)
dp[0][j] = INT_MAX;
for ( int i = 1; i <= arr.size(); i++)
{
for ( int j = 1; j <= target; j++)
{
if (arr[i - 1] > j)
{
dp[i][j] = dp[i - 1][j];
}
else
{
dp[i][j] = min(dp[i - 1][j],
(dp[i][j - arr[i - 1]]) !=
INT_MAX ?
(dp[i][j - arr[i - 1]] + 1) :
INT_MAX);
}
}
}
if (dp[arr.size()][target] == INT_MAX)
{
return -1;
}
else
{
return dp[arr.size()][target];
}
}
int main()
{
vector< int > arr = { 2, 3, 5, 4, 1 };
int target = 11;
int n = arr.size();
cout << minlt(arr, target, n);
}
|
Java
import java.util.*;
class GFG{
static int minlt( int [] arr, int target, int n)
{
int [][] dp = new int [arr.length + 1 ][target + 1 ];
for ( int [] row : dp)
Arrays.fill(row, - 1 );
for ( int i = 0 ; i < arr.length + 1 ; i++)
dp[i][ 0 ] = 0 ;
for ( int j = 0 ; j < target + 1 ; j++)
dp[ 0 ][j] = Integer.MAX_VALUE;
for ( int i = 1 ; i <= arr.length; i++)
{
for ( int j = 1 ; j <= target; j++)
{
if (arr[i - 1 ] > j)
{
dp[i][j] = dp[i - 1 ][j];
}
else
{
dp[i][j] = Math.min(dp[i - 1 ][j],
(dp[i][j - arr[i - 1 ]]) !=
Integer.MAX_VALUE ?
(dp[i][j - arr[i - 1 ]] + 1 ) :
Integer.MAX_VALUE);
}
}
}
if (dp[arr.length][target] == Integer.MAX_VALUE)
{
return - 1 ;
}
else
{
return dp[arr.length][target];
}
}
public static void main (String[] args)
{
int [] arr = { 2 , 3 , 5 , 4 , 1 };
int target = 11 ;
int n = arr.length;
System.out.print(minlt(arr, target, n));
}
}
|
Python3
import sys
def minlt(arr, target, n):
dp = [[ - 1 for _ in range (target + 1 )]\
for _ in range ( len (arr) + 1 )]
for i in range ( len (arr) + 1 ):
dp[i][ 0 ] = 0
for j in range (target + 1 ):
dp[ 0 ][j] = sys.maxsize
for i in range ( 1 , len (arr) + 1 ):
for j in range ( 1 , target + 1 ):
if arr[i - 1 ] > j:
dp[i][j] = dp[i - 1 ][j]
else :
dp[i][j] = min (dp[i - 1 ][j], \
1 + dp[i][j - arr[i - 1 ]])
return dp[ - 1 ][ - 1 ]
if dp[ - 1 ][ - 1 ] = = sys.maxsize:
return ( - 1 )
else :
return dp[ - 1 ][ - 1 ]
arr = [ 2 , 3 , 5 , 4 , 1 ]
target = 11
n = len (arr)
print (minlt(arr, target, n))
|
C#
using System;
class GFG{
static int minlt( int [] arr,
int target,
int n)
{
int [,] dp = new int [arr.Length + 1,
target + 1];
for ( int i = 0;
i < arr.Length + 1; i++)
{
for ( int j = 0;
j < target + 1; j++)
{
dp[i, j] = -1;
}
}
for ( int i = 0;
i < arr.Length + 1; i++)
dp[i, 0] = 0;
for ( int j = 0;
j < target + 1; j++)
dp[0, j] = int .MaxValue;
for ( int i = 1;
i <= arr.Length; i++)
{
for ( int j = 1;
j <= target; j++)
{
if (arr[i - 1] > j)
{
dp[i, j] = dp[i - 1, j];
}
else
{
dp[i, j] = Math.Min(dp[i - 1, j],
(dp[i, j -
arr[i - 1]]) !=
int .MaxValue ?
(dp[i, j -
arr[i - 1]] + 1) :
int .MaxValue);
}
}
}
if (dp[arr.Length,
target] == int .MaxValue)
{
return -1;
}
else
{
return dp[arr.Length,
target];
}
}
public static void Main(String[] args)
{
int [] arr = {2, 3, 5, 4, 1};
int target = 11;
int n = arr.Length;
Console.Write(
minlt(arr, target, n));
}
}
|
Javascript
<script>
function minlt(arr, target, n)
{
var dp = Array.from(Array(arr.length+1),
()=>Array(target+1).fill(-1));
for ( var i = 0; i < arr.length + 1; i++)
dp[i][0] = 0;
for ( var j = 0; j < target + 1; j++)
dp[0][j] = 1000000000;
for ( var i = 1; i <= arr.length; i++)
{
for ( var j = 1; j <= target; j++)
{
if (arr[i - 1] > j)
{
dp[i][j] = dp[i - 1][j];
}
else
{
dp[i][j] = Math.min(dp[i - 1][j],
(dp[i][j - arr[i - 1]]) !=
1000000000 ?
(dp[i][j - arr[i - 1]] + 1) :
1000000000);
}
}
}
if (dp[arr.length][target] == 1000000000)
{
return -1;
}
else
{
return dp[arr.length][target];
}
}
var arr = [2, 3, 5, 4, 1];
var target = 11;
var n = arr.length;
document.write( minlt(arr, target, n));
</script>
|
Time Complexity: O(N*Target)
Auxiliary Space: O(N*Target)
Efficient approach: Space Optimization
In the previous approach, the dp[i][j] is depend upon the previous row and current row values but it is using space of n* target 2D matrix. So to optimize the space complexity we use a 1D vector of size target + 1 just to store the previous and current computation.
Steps that were to follow the above approach:
- Create a vector ‘dp‘ of size target+1 and initialize all values to -1.
- Initialize the first element of ‘dp’ to 0, since a sum of 0 can be achieved by selecting no elements.
- Loop through the array ‘arr’ from the second element to the last, and for each element:
- Loop through the ‘dp’ vector from ‘target‘ down to 1.
- If the current element of ‘arr’ is greater than the current index of ‘dp’, continue to the next index.
- If the current index of ‘dp’ minus the current element of ‘arr’ is not equal to -1, update ‘dp’ with the minimum value between the current value of ‘dp’ at the
- current index and ‘dp‘ at the current index minus the current element of ‘arr’ plus 1.
- At last return the final answer stored in dp[target].
Below is the code to implement the above steps:
C++
#include <bits/stdc++.h>
using namespace std;
int minlt(vector< int > arr, int target, int n)
{
vector< int > dp(target + 1, -1);
dp[0] = 0;
for ( int i = 1; i <= n; i++) {
for ( int j = target; j >= 1; j--) {
if (arr[i - 1] > j) {
continue ;
}
else {
if (dp[j - arr[i - 1]] != -1) {
if (dp[j] == -1) {
dp[j] = dp[j - arr[i - 1]] + 1;
}
else {
dp[j] = min(dp[j],
dp[j - arr[i - 1]] + 1);
}
}
}
}
}
return dp[target];
}
int main()
{
vector< int > arr = { 2, 3, 5, 4, 1 };
int target = 11;
int n = arr.size();
cout << minlt(arr, target, n);
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int minlt(List<Integer> arr, int target, int n) {
int [] dp = new int [target + 1 ];
Arrays.fill(dp, - 1 );
dp[ 0 ] = 0 ;
for ( int i = 1 ; i <= n; i++) {
for ( int j = target; j >= 1 ; j--) {
if (arr.get(i - 1 ) > j) {
continue ;
} else {
if (dp[j - arr.get(i - 1 )] != - 1 ) {
if (dp[j] == - 1 ) {
dp[j] = dp[j - arr.get(i - 1 )] + 1 ;
} else {
dp[j] = Math.min(dp[j], dp[j - arr.get(i - 1 )] + 1 );
}
}
}
}
}
return dp[target];
}
public static void main(String[] args) {
List<Integer> arr = Arrays.asList( 2 , 3 , 5 , 4 , 1 );
int target = 11 ;
int n = arr.size();
System.out.println(minlt(arr, target, n));
}
}
|
Python3
def min_subarray_with_sum(arr, target_sum):
n = len (arr)
dp = [ - 1 ] * (target_sum + 1 )
dp[ 0 ] = 0
for i in range ( 1 , n + 1 ):
for j in range (target_sum, 0 , - 1 ):
if arr[i - 1 ] > j:
continue
else :
if dp[j - arr[i - 1 ]] ! = - 1 :
if dp[j] = = - 1 :
dp[j] = dp[j - arr[i - 1 ]] + 1
else :
dp[j] = min (dp[j], dp[j - arr[i - 1 ]] + 1 )
return dp[target_sum]
arr = [ 2 , 3 , 5 , 4 , 1 ]
target_sum = 11
print (min_subarray_with_sum(arr, target_sum))
|
C#
using System;
namespace ConsoleApp1
{
class Program
{
static int minlt( int [] arr, int target, int n)
{
int [] dp = new int [target + 1];
Array.Fill(dp, -1);
dp[0] = 0;
for ( int i = 1; i <= n; i++)
{
for ( int j = target; j >= 1; j--)
{
if (arr[i - 1] > j)
{
continue ;
}
else
{
if (dp[j - arr[i - 1]] != -1)
{
if (dp[j] == -1)
{
dp[j] = dp[j - arr[i - 1]] + 1;
}
else
{
dp[j] = Math.Min(dp[j], dp[j - arr[i - 1]] + 1);
}
}
}
}
}
return dp[target];
}
static void Main( string [] args)
{
int [] arr = { 2, 3, 5, 4, 1 };
int target = 11;
int n = arr.Length;
Console.WriteLine(minlt(arr, target, n));
}
}
}
|
Javascript
function minlt(arr, target, n) {
let dp = new Array(target + 1).fill(-1);
dp[0] = 0;
for (let i = 1; i <= n; i++) {
for (let j = target; j >= 1; j--) {
if (arr[i - 1] > j) {
continue ;
}
else {
if (dp[j - arr[i - 1]] != -1) {
if (dp[j] == -1) {
dp[j] = dp[j - arr[i - 1]] + 1;
}
else {
dp[j] = Math.min(dp[j], dp[j - arr[i - 1]] + 1);
}
}
}
}
}
return dp[target];
}
let arr = [ 2, 3, 5, 4, 1 ];
let target = 11;
let n = arr.length;
console.log(minlt(arr, target, n));
|
Output
3
Time Complexity: O(N*target)
Auxiliary Space: O(N*Target)
Last Updated :
25 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...