Open In App

Combinational Sum

Last Updated : 23 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of positive integers arr[] and an integer x, The task is to find all unique combinations in arr[] where the sum is equal to x. 
The same repeated number may be chosen from arr[] an unlimited number of times. Elements in a combination (a1, a2, …, ak) must be printed in non-descending order. (ie, a1 <= a2 <= … <= ak). If there is no combination possible print “Empty”.

Examples: 

Input: arr[] = 2, 4, 6, 8, x = 8
Output: 
[2, 2, 2, 2]
[2, 2, 4]
[2, 6]
[4, 4]
[8]

Recommended Practice

Approach:

Recursively find all combinations and if the current combination sums up to give X then add this combination in the final set of combinations.

Follow the below steps to implement the idea:

  • Sort the array arr[] and remove all the duplicates from the arr[] then create a temporary vector r. to store every combination and a vector of vector res.
  • Recursively follow: 
    • If at any time sub-problem sum == 0 then add that array to the res (vector of vectors).
    • Run a while loop till the sum – arr[I] is not negative and i is less than arr.size().
      • Push arr[i] in r and recursively call for i and sum-arr[i] ,then increment i by 1.
      • pop r[i] from back and backtrack. 

Below is the implementation of the above approach.

C++




// C++ program to find all combinations that
// sum to a given value
#include <bits/stdc++.h>
using namespace std;
 
// Print all members of ar[] that have given
void findNumbers(vector<int>& ar, int sum,
                 vector<vector<int> >& res, vector<int>& r,
                 int i)
{
    // if we get exact answer
    if (sum == 0) {
        res.push_back(r);
        return;
    }
 
    // Recur for all remaining elements that
    // have value smaller than sum.
    while (i < ar.size() && sum - ar[i] >= 0) {
 
        // Till every element in the array starting
        // from i which can contribute to the sum
        r.push_back(ar[i]); // add them to list
 
        // recursive call for next numbers
        findNumbers(ar, sum - ar[i], res, r, i);
        i++;
 
        // Remove number from list (backtracking)
        r.pop_back();
    }
}
 
// Returns all combinations
// of ar[] that have given
// sum.
vector<vector<int> > combinationSum(vector<int>& ar,
                                    int sum)
{
    // sort input array
    sort(ar.begin(), ar.end());
 
    // remove duplicates
    ar.erase(unique(ar.begin(), ar.end()), ar.end());
 
    vector<int> r;
    vector<vector<int> > res;
    findNumbers(ar, sum, res, r, 0);
 
    return res;
}
 
// Driver code
int main()
{
    vector<int> ar;
    ar.push_back(2);
    ar.push_back(4);
    ar.push_back(6);
    ar.push_back(8);
    int n = ar.size();
 
    int sum = 8; // set value of sum
    vector<vector<int> > res = combinationSum(ar, sum);
 
    // If result is empty, then
    if (res.size() == 0) {
        cout << "Empty";
        return 0;
    }
 
    // Print all combinations stored in res.
    for (int i = 0; i < res.size(); i++) {
        if (res[i].size() > 0) {
            cout << " ( ";
            for (int j = 0; j < res[i].size(); j++)
                cout << res[i][j] << " ";
            cout << ")";
        }
    }
  return 0;
}


Java




// Java program to find all combinations that
// sum to a given value
import java.io.*;
import java.util.*;
 
class GFG {
 
    static ArrayList<ArrayList<Integer> >
    combinationSum(ArrayList<Integer> arr, int sum)
    {
        ArrayList<ArrayList<Integer> > ans
            = new ArrayList<>();
        ArrayList<Integer> temp = new ArrayList<>();
 
        // first do hashing since hashset does not always
        // sort
        //  removing the duplicates using HashSet and
        // Sorting the arrayList
 
        Set<Integer> set = new HashSet<>(arr);
        arr.clear();
        arr.addAll(set);
        Collections.sort(arr);
 
        findNumbers(ans, arr, sum, 0, temp);
        return ans;
    }
 
    static void
    findNumbers(ArrayList<ArrayList<Integer> > ans,
                ArrayList<Integer> arr, int sum, int index,
                ArrayList<Integer> temp)
    {
 
        if (sum == 0) {
 
            // Adding deep copy of list to ans
 
            ans.add(new ArrayList<>(temp));
            return;
        }
 
        for (int i = index; i < arr.size(); i++) {
 
            // checking that sum does not become negative
 
            if ((sum - arr.get(i)) >= 0) {
 
                // adding element which can contribute to
                // sum
 
                temp.add(arr.get(i));
 
                findNumbers(ans, arr, sum - arr.get(i), i,
                            temp);
 
                // removing element from list (backtracking)
                temp.remove(arr.get(i));
            }
        }
    }
 
    // Driver Code
 
    public static void main(String[] args)
    {
        ArrayList<Integer> arr = new ArrayList<>();
 
        arr.add(2);
        arr.add(4);
        arr.add(6);
        arr.add(8);
 
        int sum = 8;
 
        ArrayList<ArrayList<Integer> > ans
            = combinationSum(arr, sum);
 
        // If result is empty, then
        if (ans.size() == 0) {
            System.out.println("Empty");
            return;
        }
 
        // print all combinations stored in ans
 
        for (int i = 0; i < ans.size(); i++) {
 
            System.out.print("(");
            for (int j = 0; j < ans.get(i).size(); j++) {
                System.out.print(ans.get(i).get(j) + " ");
            }
            System.out.print(") ");
        }
    }
}


Python3




# Python3 program to find all combinations that
# sum to a given value
 
def combinationSum(arr, sum):
    ans = []
    temp = []
 
    # first do hashing nothing but set{}
    # since set does not always sort
    # removing the duplicates using Set and
    # Sorting the List
    arr = sorted(list(set(arr)))
    findNumbers(ans, arr, temp, sum, 0)
    return ans
 
def findNumbers(ans, arr, temp, sum, index):
     
    if(sum == 0):
         
        # Adding deep copy of list to ans
        ans.append(list(temp))
        return
       
    # Iterate from index to len(arr) - 1
    for i in range(index, len(arr)):
 
        # checking that sum does not become negative
        if(sum - arr[i]) >= 0:
 
            # adding element which can contribute to
            # sum
            temp.append(arr[i])
            findNumbers(ans, arr, temp, sum-arr[i], i)
 
            # removing element from list (backtracking)
            temp.remove(arr[i])
 
 
# Driver Code
arr = [2, 4, 6, 8]
sum = 8
ans = combinationSum(arr, sum)
 
# If result is empty, then
if len(ans) <= 0:
    print("empty")
     
# print all combinations stored in ans
for i in range(len(ans)):
 
    print("(", end=' ')
    for j in range(len(ans[i])):
        print(str(ans[i][j])+" ", end=' ')
    print(")", end=' ')
 
 
# This Code Is Contributed by Rakesh(vijayarigela09)


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
using System.Collections;
 
class GFG {
 
    static List<List<int> >
    combinationSum(List<int> arr, int sum)
    {
        List<List<int> > ans
            = new List<List<int> >();
        List<int> temp = new List<int>();
 
        // first do hashing since hashset does not always
        // sort
        //  removing the duplicates using HashSet and
        // Sorting the List
 
        HashSet<int> set = new HashSet<int>(arr);
        arr.Clear();
        arr.AddRange(set);
        arr.Sort();
 
        findNumbers(ans, arr, sum, 0, temp);
        return ans;
    }
 
    static void
    findNumbers(List<List<int> > ans,
                List<int> arr, int sum, int index,
                List<int> temp)
    {
 
        if (sum == 0) {
 
            // Adding deep copy of list to ans
 
            ans.Add(new List<int>(temp));
            return;
        }
 
        for (int i = index; i < arr.Count; i++) {
 
            // checking that sum does not become negative
 
            if ((sum - arr[i]) >= 0) {
 
                // Adding element which can contribute to
                // sum
 
                temp.Add(arr[i]);
 
                findNumbers(ans, arr, sum - arr[i], i,
                            temp);
 
                // removing element from list (backtracking)
                temp.Remove(arr[i]);
            }
        }
    }
 
    // Driver Code
 
    public static void Main()
    {
        List<int> arr = new List<int>();
         
        arr.Add(2);
        arr.Add(4);
        arr.Add(6);
        arr.Add(8);
 
        int sum = 8;
 
        List<List<int> > ans
            = combinationSum(arr, sum);
 
        // If result is empty, then
        if (ans.Count == 0) {
            Console.WriteLine("Empty");
            return;
        }
 
        // print all combinations stored in ans
 
        for (int i = 0; i < ans.Count; i++) {
 
            Console.Write("(");
            for (int j = 0; j < ans[i].Count; j++) {
                Console.Write(ans[i][j] + " ");
            }
            Console.Write(") ");
        }
    }
}
 
// This code is contributed by ShubhamSingh10


Javascript




<script>
// Javascript program to find all combinations that
// sum to a given value
 
function combinationSum(arr, sum) {
    let ans = new Array();
    let temp = new Array();
 
    // first do hashing since hashset does not always
    // sort
    //  removing the duplicates using HashSet and
    // Sorting the arrayList
 
    let set = new Set([...arr]);
    arr = [...set];
    arr.sort()
 
    findNumbers(ans, arr, sum, 0, temp);
    return ans;
}
 
function findNumbers(ans, arr, sum, index, temp) {
 
    if (sum == 0) {
 
        // pushing deep copy of list to ans
 
        ans.push([...temp]);
        return;
    }
 
    for (let i = index; i < arr.length; i++) {
 
        // checking that sum does not become negative
 
        if ((sum - arr[i]) >= 0) {
 
            // pushing element which can contribute to
            // sum
 
            temp.push(arr[i]);
 
            findNumbers(ans, arr, sum - arr[i], i, temp);
 
            // removing element from list (backtracking)
            temp.splice(temp.indexOf(arr[i]), 1);
        }
    }
}
 
// Driver Code
 
 
let arr = []
 
arr.push(2);
arr.push(4);
arr.push(6);
arr.push(8);
 
let sum = 8;
 
let ans = combinationSum(arr, sum);
 
// If result is empty, then
if (ans.length == 0) {
    document.write("Empty");
}
 
// print all combinations stored in ans
for (let i = 0; i < ans.length; i++) {
 
    document.write("(");
    for (let j = 0; j < ans[i].length; j++) {
        document.write(" ", ans[i][j] + " ");
    }
    document.write(") ");
}
 
// This code is contributed by saurabh_jaiswal.
</script>


Output

 ( 2 2 2 2 ) ( 2 2 4 ) ( 2 6 ) ( 4 4 ) ( 8 )

Time Complexity: O(k*(2^n)) where n is the size of array, and k is average length
Auxiliary Space: O(k*x) where is x is number of possible combinations

 



Previous Article
Next Article

Similar Reads

Maximum sum subarray having sum less than given sum using Set
Given an array arr[] of length N and an integer K, the task is the find the maximum sum subarray with a sum less than K.Note: If K is less than the minimum element, then return INT_MIN. Examples: Input: arr[] = {-1, 2, 2}, K = 4 Output: 3 Explanation: The subarray with maximum sum which is less than 4 is {-1, 2, 2}. The subarray {2, 2} has maximum
7 min read
Maximum sum subarray having sum less than or equal to given sum
Given an array of non-negative integers and a sum. We have to find sum of the subarray having a maximum sum less than or equal to the given sum in the array. Note: Given array contains only non-negative integers. Examples: Input: arr[] = { 1, 2, 3, 4, 5 } sum = 11Output: 10Subarray having maximum sum is { 1, 2, 3, 4 }Input: arr[] = { 2, 4, 6, 8, 10
10 min read
Count of numbers satisfying m + sum(m) + sum(sum(m)) = N
Given an integer N, find out the count of numbers(m) that satisfy the condition m + sum(m) + sum (sum(m)) = N, where sum(m) denotes the sum of digits in m. Given N &lt;= 10e9. Examples: Input: 9 Output: 1 Explanation: Only 1 positive integer satisfies the condition that is 3, 3 + sum(3) + sum(sum(3)) = 3 + 3 + 3 = 9 Input: 9939 Output: 4 Explanatio
9 min read
Maximum subarray sum in O(n) using prefix sum
Given an Array of Positive and Negative Integers, find out the Maximum Subarray Sum in that Array. Examples: Input1 : arr = {-2, -3, 4, -1, -2, 1, 5, -3} Output1 : 7 Input2 : arr = {4, -8, 9, -4, 1, -8, -1, 6} Output2 : 9 Kadane's Algorithm solves this problem using Dynamic Programming approach in linear time. Here is another approach using Dynamic
8 min read
Construct sum-array with sum of elements in given range
You are given an array of n-elements and an odd-integer m. You have to construct a new sum_array from given array such that sum_array[i] = ?arr[j] for (i-(m/2)) &lt; j (i+(m/2)). note : for 0 &gt; j or j &gt;= n take arr[j] = 0. Examples: Input : arr[] = {1, 2, 3, 4, 5}, m = 3 Output : sum_array = {3, 6, 9, 12, 9} Explanation : sum_array[0] = arr[0
7 min read
Minimum array size after repeated replacement of even sum pair with sum
Given an array of size N. Choose a random pair of elements from the sequence such that their sum is even, delete those two elements from the sequence and insert their sum into the sequence instead in order to minimize the length of the array. Finally, print the minimum possible size of the array. Examples : Input : 88 98 1 7 3 Output : 2 By followi
6 min read
Count rows/columns with sum equals to diagonal sum
Given an n x n square matrix, count all rows and columns whose sum is equal to the sum of any principal diagonal or secondary diagonal. Examples: Input : n = 3 arr[][] = { {1, 2, 3}, {4, 5, 2}, {7, 9, 10}}; Output : 2 In first example sum of principal diagonal = (1 + 5 + 10) = 16 and sum of secondary diagonal = (3 + 5 + 7) = 15. Input: n = 4 arr[][
8 min read
Check if sum of digits in the left half is divisible by sum of digits in the right half in the largest permutation of N
Given a positive integer N, the task is to maximize the integer N by rearranging the digits and check if the sum of the left half digits is divisible by the sum of the right half digits or not. If found to be true, then print "Yes". Otherwise, print "No". If the number of digits(say D) in the given number N is odd, then consider any of the two poss
8 min read
Find Sum of all unique sub-array sum for a given array.
Given an array of n-positive elements. The sub-array sum is defined as the sum of all elements of a particular sub-array, the task is to find the sum of all unique sub-array sum. Note: Unique Sub-array sum means no other sub-array will have the same sum value. Examples: Input : arr[] = {3, 4, 5} Output : 40 Explanation: All possible unique sub-arra
10 min read
Min sum of set of positive integers so that sum of no two elements is K
Given two positive integers N and K. Create a set of size N containing distinct positive integers such that the sum of no two integers is K, the task is to find the minimum possible sum of the set that meets the above criteria. Since the answer may be large, print it modulo 10^9+7. Note: It is guaranteed that it is always possible to make a set tha
6 min read