Given an array of non-negative integers and a value sum, determine if there is a subset of the given set with sum equal to given sum.
Examples:
Input : arr[] = {4, 1, 10, 12, 5, 2},
sum = 9
Output : TRUE
{4, 5} is a subset with sum 9.
Input : arr[] = {1, 8, 2, 5},
sum = 4
Output : FALSE
There exists no subset with sum 4.
We have discussed a Dynamic Programming based solution in below post.
Dynamic Programming | Set 25 (Subset Sum Problem)
The solution discussed above requires O(n * sum) space and O(n * sum) time. We can optimize space. We create a boolean 2D array subset[2][sum+1]. Using bottom-up manner we can fill up this table. The idea behind using 2 in “subset[2][sum+1]” is that for filling a row only the values from previous row are required. So alternate rows are used either making the first one as current and second as previous or the first as previous and second as current.
C++
#include <iostream>
using namespace std;
bool isSubsetSum( int arr[], int n, int sum)
{
bool subset[2][sum + 1];
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j <= sum; j++) {
if (j == 0)
subset[i % 2][j] = true ;
else if (i == 0)
subset[i % 2][j] = false ;
else if (arr[i - 1] <= j)
subset[i % 2][j] = subset[(i + 1) % 2]
[j - arr[i - 1]] || subset[(i + 1) % 2][j];
else
subset[i % 2][j] = subset[(i + 1) % 2][j];
}
}
return subset[n % 2][sum];
}
int main()
{
int arr[] = { 6, 2, 5 };
int sum = 7;
int n = sizeof (arr) / sizeof (arr[0]);
if (isSubsetSum(arr, n, sum) == true )
cout << "There exists a subset with given sum" ;
else
cout << "No subset exists with given sum" ;
return 0;
}
|
C
#include <stdio.h>
#include <stdbool.h>
bool isSubsetSum( int arr[], int n, int sum)
{
bool subset[2][sum + 1];
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j <= sum; j++) {
if (j == 0)
subset[i % 2][j] = true ;
else if (i == 0)
subset[i % 2][j] = false ;
else if (arr[i - 1] <= j)
subset[i % 2][j] = subset[(i + 1) % 2]
[j - arr[i - 1]] || subset[(i + 1) % 2][j];
else
subset[i % 2][j] = subset[(i + 1) % 2][j];
}
}
return subset[n % 2][sum];
}
int main()
{
int arr[] = { 6, 2, 5 };
int sum = 7;
int n = sizeof (arr) / sizeof (arr[0]);
if (isSubsetSum(arr, n, sum) == true )
printf ( "There exists a subset with given sum" );
else
printf ( "No subset exists with given sum" );
return 0;
}
|
Java
public class Subset_sum {
static boolean isSubsetSum( int arr[], int n, int sum)
{
boolean subset[][] = new boolean [ 2 ][sum + 1 ];
for ( int i = 0 ; i <= n; i++) {
for ( int j = 0 ; j <= sum; j++) {
if (j == 0 )
subset[i % 2 ][j] = true ;
else if (i == 0 )
subset[i % 2 ][j] = false ;
else if (arr[i - 1 ] <= j)
subset[i % 2 ][j] = subset[(i + 1 ) % 2 ]
[j - arr[i - 1 ]] || subset[(i + 1 ) % 2 ][j];
else
subset[i % 2 ][j] = subset[(i + 1 ) % 2 ][j];
}
}
return subset[n % 2 ][sum];
}
public static void main(String args[])
{
int arr[] = { 1 , 2 , 5 };
int sum = 7 ;
int n = arr.length;
if (isSubsetSum(arr, n, sum) == true )
System.out.println( "There exists a subset with" +
" given sum" );
else
System.out.println( "No subset exists with" +
" given sum" );
}
}
|
Python
def isSubsetSum(arr, n, sum ):
subset = [[ False for j in range ( sum + 1 )] for i in range ( 3 )]
for i in range (n + 1 ):
for j in range ( sum + 1 ):
if (j = = 0 ):
subset[i % 2 ][j] = True
elif (i = = 0 ):
subset[i % 2 ][j] = False
elif (arr[i - 1 ] < = j):
subset[i % 2 ][j] = subset[(i + 1 ) % 2 ][j - arr[i - 1 ]] or subset[(i + 1 )
% 2 ][j]
else :
subset[i % 2 ][j] = subset[(i + 1 ) % 2 ][j]
return subset[n % 2 ][ sum ]
arr = [ 6 , 2 , 5 ]
sum = 7
n = len (arr)
if (isSubsetSum(arr, n, sum ) = = True ):
print ( "There exists a subset with given sum" )
else :
print ( "No subset exists with given sum" )
|
C#
using System;
public class Subset_sum {
static bool isSubsetSum( int []arr, int n, int sum)
{
bool [,]subset = new bool [2,sum + 1];
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j <= sum; j++) {
if (j == 0)
subset[i % 2,j] = true ;
else if (i == 0)
subset[i % 2,j] = false ;
else if (arr[i - 1] <= j)
subset[i % 2,j] = subset[(i + 1) % 2,j - arr[i - 1]] || subset[(i + 1) % 2,j];
else
subset[i % 2,j] = subset[(i + 1) % 2,j];
}
}
return subset[n % 2,sum];
}
public static void Main()
{
int []arr = { 1, 2, 5 };
int sum = 7;
int n = arr.Length;
if (isSubsetSum(arr, n, sum) == true )
Console.WriteLine( "There exists a subset with" +
"given sum" );
else
Console.WriteLine( "No subset exists with" +
"given sum" );
}
}
|
PHP
<?php
function isSubsetSum( $arr , $n , $sum )
{
$subset [2][ $sum + 1] = array ();
for ( $i = 0; $i <= $n ; $i ++)
{
for ( $j = 0; $j <= $sum ; $j ++)
{
if ( $j == 0)
$subset [ $i % 2][ $j ] = true;
else if ( $i == 0)
$subset [ $i % 2][ $j ] = false;
else if ( $arr [ $i - 1] <= $j )
$subset [ $i % 2][ $j ] = $subset [( $i + 1) % 2]
[ $j - $arr [ $i - 1]] ||
$subset [( $i + 1) % 2][ $j ];
else
$subset [ $i % 2][ $j ] = $subset [( $i + 1) % 2][ $j ];
}
}
return $subset [ $n % 2][ $sum ];
}
$arr = array ( 6, 2, 5 );
$sum = 7;
$n = sizeof( $arr );
if (isSubsetSum( $arr , $n , $sum ) == true)
echo ( "There exists a subset with given sum" );
else
echo ( "No subset exists with given sum" );
?>
|
Javascript
<script>
function isSubsetSum(arr, n, sum)
{
let subset = new Array(2);
for ( var i = 0; i < subset.length; i++) {
subset[i] = new Array(2);
}
for (let i = 0; i <= n; i++) {
for (let j = 0; j <= sum; j++) {
if (j == 0)
subset[i % 2][j] = true ;
else if (i == 0)
subset[i % 2][j] = false ;
else if (arr[i - 1] <= j)
subset[i % 2][j] = subset[(i + 1) % 2]
[j - arr[i - 1]] || subset[(i + 1) % 2][j];
else
subset[i % 2][j] = subset[(i + 1) % 2][j];
}
}
return subset[n % 2][sum];
}
let arr = [ 1, 2, 5 ];
let sum = 7;
let n = arr.length;
if (isSubsetSum(arr, n, sum) == true )
document.write( "There exists a subset with" +
"given sum" );
else
document.write( "No subset exists with" +
"given sum" );
</script>
|
OutputThere exists a subset with given sum
Another Approach: To further reduce space complexity, we create a boolean 1D array subset[sum+1]. Using bottom-up manner we can fill up this table. The idea is that we can check if the sum till position “i” is possible then if the current element in the array at position j is x, then sum i+x is also possible. We traverse the sum array from back to front so that we don’t count any element twice.
Here’s the code for the given approach:
C++
#include <iostream>
using namespace std;
bool isPossible( int elements[], int sum, int n)
{
int dp[sum + 1];
dp[0] = 1;
for ( int i = 0; i < n; i++)
{
for ( int j = sum; j >= elements[i]; j--)
{
if (dp[j - elements[i]] == 1)
dp[j] = 1;
}
}
if (dp[sum] == 1)
return true ;
return false ;
}
int main()
{
int elements[] = { 6, 2, 5 };
int n = sizeof (elements) / sizeof (elements[0]);
int sum = 7;
if (isPossible(elements, sum, n))
cout << ( "YES" );
else
cout << ( "NO" );
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static boolean isPossible( int elements[], int sum)
{
int dp[] = new int [sum + 1 ];
dp[ 0 ] = 1 ;
for ( int i = 0 ; i < elements.length; i++) {
for ( int j = sum; j >= elements[i]; j--) {
if (dp[j - elements[i]] == 1 )
dp[j] = 1 ;
}
}
if (dp[sum] == 1 )
return true ;
return false ;
}
public static void main(String[] args) throws Exception
{
int elements[] = { 6 , 2 , 5 };
int sum = 7 ;
if (isPossible(elements, sum))
System.out.println( "YES" );
else
System.out.println( "NO" );
}
}
|
Python3
def isPossible(elements, target):
dp = [ False ] * (target + 1 )
dp[ 0 ] = True
for ele in elements:
for j in range (target, ele - 1 , - 1 ):
if dp[j - ele]:
dp[j] = True
return dp[target]
arr = [ 6 , 2 , 5 ]
target = 7
if isPossible(arr, target):
print ( "YES" )
else :
print ( "NO" )
|
C#
using System;
class GFG {
static Boolean isPossible( int []elements, int sum)
{
int []dp = new int [sum + 1];
dp[0] = 1;
for ( int i = 0; i < elements.Length; i++)
{
for ( int j = sum; j >= elements[i]; j--) {
if (dp[j - elements[i]] == 1)
dp[j] = 1;
}
}
if (dp[sum] == 1)
return true ;
return false ;
}
public static void Main(String[] args)
{
int []elements = { 6, 2, 5 };
int sum = 7;
if (isPossible(elements, sum))
Console.Write( "YES" );
else
Console.Write( "NO" );
}
}
|
Javascript
<script>
function isPossible(elements, sum)
{
var dp = [sum + 1];
dp[0] = 1;
for ( var i = 0; i < elements.length; i++)
{
for ( var j = sum; j >= elements[i]; j--) {
if (dp[j - elements[i]] == 1)
dp[j] = 1;
}
}
if (dp[sum] == 1)
return true ;
return false ;
}
var elements = [ 6, 2, 5 ];
var sum = 7;
if (isPossible(elements, sum))
document.write( "YES" );
else
document.write( "NO" );
</script>
|
Time Complexity: O(N*K) where N is the number of elements in the array and K is total sum.
Auxiliary Space: O(K), since K extra space has been taken.
This article is contributed by Neelesh (Neelesh_Sinha). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.