📌  相关文章
📜  找到不能表示为给定数组的任何子集之和的最小正整数值

📅  最后修改于: 2022-05-13 01:57:52.781000             🧑  作者: Mango

找到不能表示为给定数组的任何子集之和的最小正整数值

给定一个正数数组,找出不能表示为给定集合的任何子集元素之和的最小正整数值。
预期时间复杂度为 O(nlogn)。
例子:

Input:  arr[] = {1, 10, 3, 11, 6, 15};
Output: 2

Input:  arr[] = {1, 1, 1, 1};
Output: 5

Input:  arr[] = {1, 1, 3, 4};
Output: 10

Input:  arr[] = {1, 2, 5, 10, 20, 40};
Output: 4

Input:  arr[] = {1, 2, 3, 4, 5, 6};
Output: 22

一个简单的解决方案是从值 1 开始,并一一检查所有值是否可以与给定数组中的值相加。该解决方案效率非常低,因为它简化为众所周知的 NP 完全问题的子集和问题。
使用一个简单的循环,我们可以在 O(N log N) 时间内解决这个问题。让输入数组为 arr[0..n-1]。我们首先按非降序对数组进行排序。令索引从 0 到 (i-1) 的元素不能表示的最小元素为“res”。我们将“res”初始化为 1(可能的最小答案)并从 i=0 开始遍历给定的数组。当我们考虑索引 i 处的元素时,有以下两种可能性:
1)我们决定'res'是最终结果:如果arr[i]大于'res',那么我们找到了'res'的差距,因为arr[i]之后的元素也将大于'res'。
2) 'res' 的值在考虑 arr[i] 后递增:如果 arr[i] 不大于 'res',则 'res' 的值递增 arr[i] 所以 'res' = 'res '+arr[i] (为什么?如果从 0 到 (i-1) 的元素可以表示 1 到 'res-1',那么从 0 到 i 的元素可以表示从 1 到 'res + arr[i] – 1')通过将 arr[i] 添加到我们已经确定要表示的 1 到 'res-1' 的所有子集)
以下是上述思想的实现。

C++
// C++ program to find the smallest positive value that cannot be
// represented as sum of subsets of a given sorted array
#include
#include
#include
using namespace std;
 
// Returns the smallest number that cannot be represented as sum
// of subset of elements from set represented by sorted array arr[0..n-1]
long long smallestpositive(vector arr, int n) {
   long long int res = 1; // Initialize result
  
   sort(arr.begin(), arr.end());
   // Traverse the array and increment 'res' if arr[i] is
   // smaller than or equal to 'res'.
   for (int i = 0; i < n && arr[i] <= res; i++)
       res = res + arr[i];
  
   return res;
  }
 
// Driver program to test above function
int main() {
   vector arr1 = {1, 3, 4, 5};
   cout << smallestpositive(arr1, arr1.size()) << endl;
  
   vector arr2 = {1, 2, 6, 10, 11, 15};
   cout << smallestpositive(arr2, arr2.size()) << endl;
  
   vector arr3 = {1, 1, 1, 1};
   cout << smallestpositive(arr3, arr3.size()) << endl;
  
   vector arr4 = {1, 1, 3, 4};
   cout << smallestpositive(arr4, arr4.size()) << endl;
  
   return 0;
 }


Java
// Java program to find the smallest positive value that cannot be
// represented as sum of subsets of a given sorted array
class FindSmallestInteger
{
    // Returns the smallest number that cannot be represented as sum
    // of subset of elements from set represented by sorted array arr[0..n-1]
    int findSmallest(int arr[], int n)
    {
        int res = 1; // Initialize result
 
        // Traverse the array and increment 'res' if arr[i] is
        // smaller than or equal to 'res'.
        for (int i = 0; i < n; i++)
        {
          if(arr[i] > res){
            return res;
           }
          else{
            res+=arr[i];
          }
        }
             
        return res;
    }
 
    // Driver program to test above functions
    public static void main(String[] args)
    {
        FindSmallestInteger small = new FindSmallestInteger();
        int arr1[] = {1, 3, 4, 5};
        int n1 = arr1.length;
        System.out.println(small.findSmallest(arr1, n1));
 
        int arr2[] = {1, 2, 6, 10, 11, 15};
        int n2 = arr2.length;
        System.out.println(small.findSmallest(arr2, n2));
 
        int arr3[] = {1, 1, 1, 1};
        int n3 = arr3.length;
        System.out.println(small.findSmallest(arr3, n3));
 
        int arr4[] = {1, 1, 3, 4};
        int n4 = arr4.length;
        System.out.println(small.findSmallest(arr4, n4));
 
    }
}
 
// This code has been contributed by Mayank Jaiswal(mayank_24)


Python3
# Python3 program to find the smallest
# positive value that cannot be
# represented as sum of subsets
# of a given sorted array
 
# Returns the smallest number
# that cannot be represented as sum
# of subset of elements from set
# represented by sorted array arr[0..n-1]
def findSmallest(arr, n):
 
    res = 1 #Initialize result
 
    # Traverse the array and increment
    # 'res' if arr[i] is smaller than
    # or equal to 'res'.
    for i in range (0, n ):
        if arr[i] <= res:
            res = res + arr[i]
        else:
            break
    return res
 
 
# Driver program to test above function
arr1 = [1, 3, 4, 5]
n1 = len(arr1)
print(findSmallest(arr1, n1))
 
arr2= [1, 2, 6, 10, 11, 15]
n2 = len(arr2)
print(findSmallest(arr2, n2))
 
arr3= [1, 1, 1, 1]
n3 = len(arr3)
print(findSmallest(arr3, n3))
 
arr4 = [1, 1, 3, 4]
n4 = len(arr4)
print(findSmallest(arr4, n4))
 
# This code is.contributed by Smitha Dinesh Semwal


C#
// C# program to find the smallest
// positive value that cannot be
// represented as sum of subsets
// of a given sorted array
using System;
 
class GFG {
     
    // Returns the smallest number that
    // cannot be represented as sum
    // of subset of elements from set
    // represented by sorted array
    // arr[0..n-1]
    static int findSmallest(int []arr, int n)
    {
         // Initialize result
         int res = 1;
 
        // Traverse the array and
        // increment 'res' if arr[i] is
        // smaller than or equal to 'res'.
        for (int i = 0; i < n &&
             arr[i] <= res; i++)
            res = res + arr[i];
 
        return res;
    }
 
    // Driver code
    public static void Main()
    {
        int []arr1 = {1, 3, 4, 5};
        int n1 = arr1.Length;
        Console.WriteLine(findSmallest(arr1, n1));
 
        int []arr2 = {1, 2, 6, 10, 11, 15};
        int n2 = arr2.Length;
        Console.WriteLine(findSmallest(arr2, n2));
 
        int []arr3 = {1, 1, 1, 1};
        int n3 = arr3.Length;
        Console.WriteLine(findSmallest(arr3, n3));
 
        int []arr4 = {1, 1, 3, 4};
        int n4 = arr4.Length;
        Console.WriteLine(findSmallest(arr4, n4));
 
    }
}
 
// This code is contributed by Sam007


PHP


Javascript


输出
2
4
5
10

输出:

2
4
5
10

上述程序的时间复杂度为 O(nlogn)。