Skip to content
Related Articles

Related Articles

Smallest subarray from a given Array with sum greater than or equal to K | Set 2
  • Difficulty Level : Medium
  • Last Updated : 21 Nov, 2020

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




// C++14 program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the smallest subarray
// sum greater than or equal to target
int smallSumSubset(vector<int> data,
                   int target, int maxVal)
{
    int sum = 0;
 
    for(int i : data)
        sum += i;
 
    // Base Case
    if (target <= 0)
        return 0;
 
    // If sum of the array
    // is less than target
    else if (sum < target)
        return maxVal;
 
    // If target is equal to
    // the sum of the array
    else if (sum == target)
        return data.size();
 
    // Required condition
    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));
    }
}
 
// Driver Code
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;
}    
 
// This code is contributed by mohit kumar 29

Java




// Java program for the above approach
import java.util.*;
import java.lang.*;
 
class GFG{
 
// Function to find the smallest subarray
// sum greater than or equal to target
static int smallSumSubset(List<Integer> data,
                          int target, int maxVal)
{
    int sum = 0;
 
    for(Integer i : data)
        sum += i;
 
    // Base Case
    if (target <= 0)
        return 0;
 
    // If sum of the array
    // is less than target
    else if (sum < target)
        return maxVal;
 
    // If target is equal to
    // the sum of the array
    else if (sum == target)
        return data.size();
 
    // Required condition
    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;
}
     
// Driver Code
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);
}
}
 
// This code is contributed by offbeat

Python3




# Python3 program for the above approach
 
# Function to find the smallest subarray
# sum greater than or equal to target
def smallSumSubset(data, target, maxVal):
    # base condition
 
    # Base Case
    if target <= 0:
        return 0
 
    # If sum of the array
    # is less than target
    elif sum(data) < target:
        return maxVal
 
    # If target is equal to
    # the sum of the array
    elif sum(data) == target:
        return len(data)
 
    # Required condition
    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))
 
 
# Driver Code
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#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to find the smallest subarray
// sum greater than or equal to target
static int smallSumSubset(List<int> data,
                   int target, int maxVal)
{
    int sum = 0;
   
    foreach(int i in data)
        sum += i;
   
    // Base Case
    if (target <= 0)
        return 0;
   
    // If sum of the array
    // is less than target
    else if (sum < target)
        return maxVal;
   
    // If target is equal to
    // the sum of the array
    else if (sum == target)
        return data.Count;
   
    // Required condition
    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;
}
 
// Driver code
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);
}
}
 
// This code is contributed by divyeshrabadiya07
Output
3

Time Complexity: O(2N)
Auxiliary Space: O(N)

Efficient Approach: The above approach can be optimized using Dynamic programming by memoizating the subproblems to avoid re-computation.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include<bits/stdc++.h>
using namespace std;
     
// Function to find the smallest subarray
// with sum greater than or equal target
int minlt(vector<int> arr, int target, int n)
{
     
    // DP table to store the
    // computed subproblems
    vector<vector<int>> dp(arr.size() + 1 ,
           vector<int> (target + 1, -1));
     
    for(int i = 0; i < arr.size() + 1; i++)
     
        // Initialize first
        // column with 0
        dp[i][0] = 0;
         
    for(int j = 0; j < target + 1; j++)
     
        // Initialize first
        // row with 0
        dp[0][j] = INT_MAX;
         
    for(int i = 1; i <= arr.size(); i++)
    {
        for(int j = 1; j <= target; j++)
        {
             
            // Check for invalid condition
            if (arr[i - 1] > j)
            {
                dp[i][j] = dp[i - 1][j];
            }
            else
            {
                 
                // Fill up the dp table
                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);
            }
        }
    }
 
    // Print the minimum length
    if (dp[arr.size()][target] == INT_MAX)
    {
        return -1;
    }
    else
    {
        return dp[arr.size()][target];
    }
}
 
// Driver code
int main()
{
    vector<int> arr = { 2, 3, 5, 4, 1 };
    int target = 11;
    int n = arr.size();
     
    cout << minlt(arr, target, n);
}
 
// This code is contributed by Surendra_Gangwar

Java




// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to find the smallest subarray
// with sum greater than or equal target
static int minlt(int[] arr, int target, int n)
{
     
    // DP table to store the
    // computed subproblems
    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++)
         
        // Initialize first
        // column with 0
        dp[i][0] = 0;
         
    for(int j = 0; j < target + 1; j++)
 
        // Initialize first
        // row with 0
        dp[0][j] = Integer.MAX_VALUE;
         
    for(int i = 1; i <= arr.length; i++)
    {
        for(int j = 1; j <= target; j++)
        {
             
            // Check for invalid condition
            if (arr[i - 1] > j)
            {
                dp[i][j] = dp[i - 1][j];
            }
            else
            {
                 
                // Fill up the dp table
                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);
            }
        }
    }
 
    // Print the minimum length
    if (dp[arr.length][target] == Integer.MAX_VALUE)
    {
        return -1;
    }
    else
    {
        return dp[arr.length][target];
    }
}
 
// Driver code
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));
}
}
 
// This code is contributed by offbeat

Python3




# Python3 program for the above approach
 
import sys
 
# Function to find the smallest subarray
# with sum greater than or equal target
def minlt(arr, target, n):
 
    # DP table to store the
    # computed subproblems
    dp = [[-1 for _ in range(target + 1)]\
    for _ in range(len(arr)+1)]
     
    for i in range(len(arr)+1):
         
        # Initialize first
        # column with 0
        dp[i][0] = 0
         
    for j in range(target + 1):
 
        # Initialize first
        # row with 0
        dp[0][j] = sys.maxsize
 
    for i in range(1, len(arr)+1):
        for j in range(1, target + 1):
 
            # Check for invalid condition
            if arr[i-1] > j:
                dp[i][j] = dp[i-1][j]
 
            else:
                # Fill up the dp table
                dp[i][j] = min(dp[i-1][j], \
                1 + dp[i][j-arr[i-1]])
                 
    return dp[-1][-1]
 
    # Print the minimum length
    if dp[-1][-1] == sys.maxsize:
        return(-1)
    else:
        return dp[-1][-1]
 
# Driver Code
arr = [2, 3, 5, 4, 1]
target = 11
n = len(arr)
 
print(minlt(arr, target, n))

C#




// C# program for the
// above approach
using System;
class GFG{
     
// Function to find the
// smallest subarray with
// sum greater than or equal
// target
static int minlt(int[] arr,
                 int target,
                 int n)
{   
  // DP table to store the
  // computed subproblems
  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++)
 
    // Initialize first
    // column with 0
    dp[i, 0] = 0;
 
  for(int j = 0;
          j < target + 1; j++)
 
    // Initialize first
    // row with 0
    dp[0, j] = int.MaxValue;
 
  for(int i = 1;
          i <= arr.Length; i++)
  {
    for(int j = 1;
            j <= target; j++)
    {
      // Check for invalid
      // condition
      if (arr[i - 1] > j)
      {
        dp[i, j] = dp[i - 1, j];
      }
      else
      {
        // Fill up the dp table
        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);
      }
    }
  }
 
  // Print the minimum
  // length
  if (dp[arr.Length,
         target] == int.MaxValue)
  {
    return -1;
  }
  else
  {
    return dp[arr.Length,
              target];
  }
}
 
// Driver code
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));
}
}
 
// This code is contributed by gauravrajput1
Output
3

Time Complexity: O(N2)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :