Find the smallest positive integer value that cannot be represented as sum of any subset of a given array
Last Updated :
14 Sep, 2023
Given an array of positive numbers, find the smallest positive integer value that cannot be represented as the sum of elements of any subset of a given set.
The expected time complexity is O(nlogn).
Examples:
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
A Simple Solution is to start from value 1 and check all values one by one if they can sum to values in the given array. This solution is very inefficient as it reduces to the subset sum problem which is a well-known NP-Complete Problem.
Using a simple loop, we can solve this problem in O(N log N) time. Let the input array be arr[0..n-1]. We first sort the array in non-decreasing order. Let the smallest element that cannot be represented by elements at indexes from 0 to (i-1) be ‘res’. We initialize ‘res’ as 1 (smallest possible answer) and traverse the given array from i=0. There are the following two possibilities when we consider element at index i:
- We decide that ‘res’ is the final result: If arr[i] is greater than ‘res’, then we found the gap which is ‘res’ because the elements after arr[i] are also going to be greater than ‘res’.
- The value of ‘res’ is incremented after considering arr[i]: If arr[i] is not greater than ‘res’, the value of ‘res’ is incremented by arr[i] so ‘res’ = ‘res’+arr[i] (why? If elements from 0 to (i-1) can
represent 1 to ‘res-1’, then elements from 0 to i can represent from 1 to ‘res + arr[i] – 1’ by adding arr[i] to all subsets that represent 1 to ‘res-1’ which we have already determined to be represented)
Following is the implementation of the above idea.
C++
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
long long smallestpositive(vector< long long > arr, int n) {
long long int res = 1;
sort(arr.begin(), arr.end());
for ( int i = 0; i < n && arr[i] <= res; i++)
res = res + arr[i];
return res;
}
int main() {
vector< long long > arr1 = {1, 3, 4, 5};
cout << smallestpositive(arr1, arr1.size()) << endl;
vector< long long > arr2 = {1, 2, 6, 10, 11, 15};
cout << smallestpositive(arr2, arr2.size()) << endl;
vector< long long > arr3 = {1, 1, 1, 1};
cout << smallestpositive(arr3, arr3.size()) << endl;
vector< long long > arr4 = {1, 1, 3, 4};
cout << smallestpositive(arr4, arr4.size()) << endl;
return 0;
}
|
Java
import java.util.Arrays;
class FindSmallestInteger
{
int findSmallest( int arr[], int n)
{
int res = 1 ;
Arrays.sort(arr);
for ( int i = 0 ; i < n; i++)
{
if (arr[i] > res){
return res;
}
else {
res+=arr[i];
}
}
return res;
}
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));
}
}
|
Python3
def findSmallest(arr, n):
res = 1
for i in range ( 0 , n ):
if arr[i] < = res:
res = res + arr[i]
else :
break
return res
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))
|
C#
using System;
class GFG {
static int findSmallest( int []arr, int n)
{
int res = 1;
for ( int i = 0; i < n &&
arr[i] <= res; i++)
res = res + arr[i];
return res;
}
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));
}
}
|
Javascript
<script>
function findSmallest(arr , n)
{
var res = 1;
for (i = 0; i < n && arr[i] <= res; i++)
res = res + arr[i];
return res;
}
var arr1 = [ 1, 3, 4, 5 ];
var n1 = arr1.length;
document.write(findSmallest(arr1, n1)+ "<br/>" );
var arr2 = [ 1, 2, 6, 10, 11, 15 ];
var n2 = arr2.length;
document.write(findSmallest(arr2, n2)+ "<br/>" );
var arr3 = [ 1, 1, 1, 1 ];
var n3 = arr3.length;
document.write(findSmallest(arr3, n3)+ "<br/>" );
var arr4 = [ 1, 1, 3, 4 ];
var n4 = arr4.length;
document.write(findSmallest(arr4, n4)+ "<br/>" );
</script>
|
PHP
<?php
function findSmallest( $arr , $n )
{
$res = 1;
for ( $i = 0; $i < $n and $arr [ $i ] <= $res ; $i ++)
$res = $res + $arr [ $i ];
return $res ;
}
$arr1 = array (1, 3, 4, 5);
$n1 = count ( $arr1 );
echo findSmallest( $arr1 , $n1 ), "\n" ;
$arr2 = array (1, 2, 6, 10, 11, 15);
$n2 = count ( $arr2 );
echo findSmallest( $arr2 , $n2 ), "\n" ;
$arr3 = array (1, 1, 1, 1);
$n3 = count ( $arr3 );
echo findSmallest( $arr3 , $n3 ), "\n" ;
$arr4 = array (1, 1, 3, 4);
$n4 = count ( $arr4 );
echo findSmallest( $arr4 , $n4 );
?>
|
The Time Complexity of the above program is O(nlogn).
The Space Complexity is O(1) in best case for heap sort.
Approach#2: Using dynamic programming
In this approach, we can use dynamic programming to solve the problem. We can create a boolean array of size (sum+1), where sum is the sum of all the elements in the array. We can then use dynamic programming to mark all the possible sums that can be obtained by selecting some of the elements in the array. Finally, we can iterate through the boolean array to find the smallest positive integer that cannot be represented as a sum of any subset of the given array.
Algorithm
1. Calculate the sum of all elements in the given array.
2. Create a boolean array of size (sum+1), initialized to False.
3. Mark arr[0] as True, as a subset with sum equal to arr[0] can be formed.
4. For each element arr[i], iterate through the boolean array from right to left, and mark arr[i]+j as True if arr[i]+j is less than or equal to sum.
5. Finally, iterate through the boolean array from left to right, and return the index of the first False element plus 1.
C++
#include <iostream>
#include <vector>
using namespace std;
int smallest_positive_integer(vector< int >& arr) {
int n = arr.size();
int s = 0;
for ( int i = 0; i < n; i++) {
s += arr[i];
}
vector< bool > dp(s+1, false );
dp[0] = true ;
for ( int i = 0; i < n; i++) {
for ( int j = s; j >= arr[i]; j--) {
if (dp[j-arr[i]]) {
dp[j] = true ;
}
}
}
for ( int i = 1; i <= s; i++) {
if (!dp[i]) {
return i;
}
}
return s+1;
}
int main() {
vector< int > arr = {1, 3, 4, 5};
cout << smallest_positive_integer(arr) << endl;
arr = {1, 2, 6, 10, 11, 15};
cout << smallest_positive_integer(arr) << endl;
arr = {1, 1, 1, 1};
cout << smallest_positive_integer(arr) << endl;
arr = {1, 1, 3, 4};
cout << smallest_positive_integer(arr) << endl;
return 0;
}
|
Java
import java.util.ArrayList;
public class GFG {
public static int smallestPositiveInteger(ArrayList<Integer> arr) {
int n = arr.size();
int s = 0 ;
for ( int i = 0 ; i < n; i++) {
s += arr.get(i);
}
boolean [] dp = new boolean [s + 1 ];
dp[ 0 ] = true ;
for ( int i = 0 ; i < n; i++) {
for ( int j = s; j >= arr.get(i); j--) {
if (dp[j - arr.get(i)]) {
dp[j] = true ;
}
}
}
for ( int i = 1 ; i <= s; i++) {
if (!dp[i]) {
return i;
}
}
return s + 1 ;
}
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>();
arr.add( 1 );
arr.add( 3 );
arr.add( 4 );
arr.add( 5 );
System.out.println(smallestPositiveInteger(arr));
arr.clear();
arr.add( 1 );
arr.add( 2 );
arr.add( 6 );
arr.add( 10 );
arr.add( 11 );
arr.add( 15 );
System.out.println(smallestPositiveInteger(arr));
arr.clear();
arr.add( 1 );
arr.add( 1 );
arr.add( 1 );
arr.add( 1 );
System.out.println(smallestPositiveInteger(arr));
arr.clear();
arr.add( 1 );
arr.add( 1 );
arr.add( 3 );
arr.add( 4 );
System.out.println(smallestPositiveInteger(arr));
}
}
|
Python3
def smallest_positive_integer(arr):
n = len (arr)
s = sum (arr)
dp = [ False ] * (s + 1 )
dp[ 0 ] = True
for i in range (n):
for j in range (s, arr[i] - 1 , - 1 ):
if dp[j - arr[i]]:
dp[j] = True
for i in range ( 1 , s + 1 ):
if not dp[i]:
return i
return s + 1
arr = [ 1 , 3 , 4 , 5 ]
print (smallest_positive_integer(arr))
arr = [ 1 , 2 , 6 , 10 , 11 , 15 ]
print (smallest_positive_integer(arr))
arr = [ 1 , 1 , 1 , 1 ]
print (smallest_positive_integer(arr))
arr = [ 1 , 1 , 3 , 4 ]
print (smallest_positive_integer(arr))
|
C#
using System;
using System.Collections.Generic;
class Program {
static int SmallestPositiveInteger(List< int > arr)
{
int n = arr.Count;
int s = 0;
for ( int i = 0; i < n; i++) {
s += arr[i];
}
bool [] dp = new bool [s + 1];
dp[0] = true ;
for ( int i = 0; i < n; i++) {
for ( int j = s; j >= arr[i]; j--) {
if (dp[j - arr[i]])
{
dp[j] = true ;
}
}
}
for ( int i = 1; i <= s; i++) {
if (!dp[i])
{
return i;
}
}
return s + 1;
}
static void Main( string [] args)
{
List< int > arr = new List< int >{ 1, 3, 4, 5 };
Console.WriteLine(SmallestPositiveInteger(arr));
arr = new List< int >{ 1, 2, 6, 10, 11, 15 };
Console.WriteLine(SmallestPositiveInteger(arr));
arr = new List< int >{ 1, 1, 1, 1 };
Console.WriteLine(SmallestPositiveInteger(arr));
arr = new List< int >{ 1, 1, 3, 4 };
Console.WriteLine(SmallestPositiveInteger(arr));
}
}
|
Javascript
function smallestPositiveInteger(arr) {
const n = arr.length;
let s = 0;
for (let i = 0; i < n; i++) {
s += arr[i];
}
const dp = new Array(s + 1).fill( false );
dp[0] = true ;
for (let i = 0; i < n; i++) {
for (let j = s; j >= arr[i]; j--) {
if (dp[j - arr[i]]) {
dp[j] = true ;
}
}
}
for (let i = 1; i <= s; i++) {
if (!dp[i]) {
return i;
}
}
return s + 1;
}
const arr1 = [1, 3, 4, 5];
console.log(smallestPositiveInteger(arr1));
const arr2 = [1, 2, 6, 10, 11, 15];
console.log(smallestPositiveInteger(arr2));
const arr3 = [1, 1, 1, 1];
console.log(smallestPositiveInteger(arr3));
const arr4 = [1, 1, 3, 4];
console.log(smallestPositiveInteger(arr4));
|
Time Complexity: O(n*sum), where n is length of array
Auxiliary Space: O(sum)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...