📌  相关文章
📜  给定Array中总和大于或等于K |的最小子数组套装2

📅  最后修改于: 2021-05-17 17:29:50             🧑  作者: Mango

给定一个由N个正整数和一个整数K组成的数组A [] ,任务是找到总和大于或等于K的最小子数组的长度。如果不存在这样的子数组,则打印-1

例子:

朴素和二进制搜索方法:对于最简单的方法和基于二进制搜索的方法,请参考给定数组中最小和总和大于或等于K的子数组。

递归方法:解决问题的最简单方法是使用递归。请按照以下步骤解决问题:

  • 如果K≤0:打印-1,因为无法获得此类子数组。
  • 如果数组的总和等于K ,则打印数组的长度作为所需答案。
  • 如果数组中的第一个元素大于K ,则打印1作为所需答案。
  • 否则,通过考虑子数组中的当前元素以及不包括它,继续查找最小的子数组。
  • 对遍历的每个元素重复上述步骤。

下面是上述方法的实现:

C++14
// C++14 program for the above approach
#include 
using namespace std;
 
// Function to find the smallest subarray
// sum greater than or equal to target
int smallSumSubset(vector 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 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 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 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 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 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 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 temp = new List();
        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 data = new List();
    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


C++
// C++ program for the above approach
#include
using namespace std;
     
// Function to find the smallest subarray
// with sum greater than or equal target
int minlt(vector arr, int target, int n)
{
     
    // DP table to store the
    // computed subproblems
    vector> dp(arr.size() + 1 ,
           vector (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 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


输出
3

时间复杂度: O(2 N )
辅助空间: O(N)

高效方法:可以通过记住子问题来避免重新计算,从而使用动态编程来优化上述方法。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include
using namespace std;
     
// Function to find the smallest subarray
// with sum greater than or equal target
int minlt(vector arr, int target, int n)
{
     
    // DP table to store the
    // computed subproblems
    vector> dp(arr.size() + 1 ,
           vector (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 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
输出
3

时间复杂度: O(N 2 )
辅助空间: O(N)