找到不能表示为给定数组的任何子集之和的最小正整数值
给定一个正数数组,找出不能表示为给定集合的任何子集元素之和的最小正整数值。
预期时间复杂度为 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)。