Open In App

Smallest subarray from a given Array with sum greater than or equal to K | Set 2

Last Updated : 25 Apr, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

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
JavaScript
<script>

// js program for the above approach

// Function to find the smallest subarray
// sum greater than or equal to target
function smallSumSubset(data, target, maxVal)
{
    let sum = 0;

    for(let i=0;i< data.length;i++) 
        sum += data[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.length;

    // Required condition
    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));
    }
}

// Driver Code
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>

Output
3

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++
// 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
JavaScript
<script>

// JavaScript program for the above approach
    
// Function to find the smallest subarray
// with sum greater than or equal target
function minlt(arr, target, n)
{
    
    // DP table to store the
    // computed subproblems
    var dp = Array.from(Array(arr.length+1), 
    ()=>Array(target+1).fill(-1));
    
    for(var i = 0; i < arr.length + 1; i++)
    
        // Initialize first
        // column with 0
        dp[i][0] = 0;
        
    for(var j = 0; j < target + 1; j++)
    
        // Initialize first
        // row with 0
        dp[0][j] = 1000000000;
        
    for(var i = 1; i <= arr.length; i++)
    {
        for(var 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]]) !=
                   1000000000 ? 
                   (dp[i][j - arr[i - 1]] + 1) : 
                   1000000000);
            }
        }
    }

    // Print the minimum length
    if (dp[arr.length][target] == 1000000000)
    {
        return -1;
    }
    else
    {
        return dp[arr.length][target]; 
    }
}

// Driver code

var arr = [2, 3, 5, 4, 1];
var target = 11;
var n = arr.length;

document.write( minlt(arr, target, n));


</script> 

Output
3

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++
// C++ code 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<int> dp(target + 1, -1);

    // Initialize first column with 0
    dp[0] = 0;

    for (int i = 1; i <= n; i++) {
        for (int j = target; j >= 1; j--) {

            // Check for invalid condition
            if (arr[i - 1] > j) {
                continue;
            }
            else {
                // Fill up the dp table
                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);
                    }
                }
            }
        }
    }

    // Print the minimum length
    return dp[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);

    return 0;
}
Java
import java.util.*;

public class Main {
    // Function to find the smallest subarray
    // with sum greater than or equal target
    public static int minlt(List<Integer> arr, int target, int n) {

        // DP table to store the
        // computed subproblems
        int[] dp = new int[target + 1];
        Arrays.fill(dp, -1);

        // Initialize first column with 0
        dp[0] = 0;

        for (int i = 1; i <= n; i++) {
            for (int j = target; j >= 1; j--) {

                // Check for invalid condition
                if (arr.get(i - 1) > j) {
                    continue;
                } else {
                    // Fill up the dp table
                    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);
                        }
                    }
                }
            }
        }

        // Print the minimum length
        return dp[target];
    }

    // Driver code
    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 table to store the computed subproblems
    dp = [-1] * (target_sum + 1)

    # Initialize first column with 0
    dp[0] = 0

    for i in range(1, n + 1):
        for j in range(target_sum, 0, -1):

            # Check for invalid condition
            if arr[i - 1] > j:
                continue
            else:
                # Fill up the dp table
                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 the minimum length
    return dp[target_sum]

# Example usage:
arr = [2, 3, 5, 4, 1]
target_sum = 11
print(min_subarray_with_sum(arr, target_sum))
C#
using System;

namespace ConsoleApp1
{
    class Program
    {
        // 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[target + 1];
            Array.Fill(dp, -1);

            // Initialize first column with 0
            dp[0] = 0;

            for (int i = 1; i <= n; i++)
            {
                for (int j = target; j >= 1; j--)
                {
                    // Check for invalid condition
                    if (arr[i - 1] > j)
                    {
                        continue;
                    }
                    else
                    {
                        // Fill up the dp table
                        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);
                            }
                        }
                    }
                }
            }

            // Print the minimum length
            return dp[target];
        }

        // Driver code
        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
// Javascript code above approach

// Function to find the smallest subarray
// with sum greater than or equal target
function minlt(arr, target, n) {

    // DP table to store the
    // computed subproblems
    let dp = new Array(target + 1).fill(-1);
    
    // Initialize first column with 0
    dp[0] = 0;
    
    for (let i = 1; i <= n; i++) {
        for (let j = target; j >= 1; j--) {
    
            // Check for invalid condition
            if (arr[i - 1] > j) {
                continue;
            }
            else {
                // Fill up the dp table
                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);
                    }
                }
            }
        }
    }
    
    // Print the minimum length
    return dp[target];
}

// Driver code
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)


Next Article

Similar Reads