Combinational Sum

23 Jun, 2022
Given an array of positive integers arr[] and a sum x, find all unique combinations in arr[] where the sum is equal to x. The same repeated number may be chosen from arr[] unlimited number of times. Elements in a combination (a1, a2, ..., ak) must be printed in non-descending order. (ie, a1 <= a2 <= ... <= ak). The combinations themselves must be sorted in ascending order, i.e., the combination with smallest first element should be printed first. If there is no combination possible the print “Empty” (without quotes).
Examples: 
Input : arr[] = 2, 4, 6, 8 
            x = 8
Output : [2, 2, 2, 2]
         [2, 2, 4]
         [2, 6]
         [4, 4]
         [8]
Since the problem is to get all the possible results, not the best or the number of result, thus we don’t need to consider DP(dynamic programming), recursion is needed to handle it.
We should use the following algorithm. 
1. Sort the array(non-decreasing).
2. First remove all the duplicates from array.
3. Then use recursion and backtracking to solve 
   the problem.
   (A) If at any time sub-problem sum == 0 then 
       add that array to the result (vector of 
       vectors).
   (B) Else if sum is negative then ignore that 
       sub-problem.
   (C) Else insert the present index in that 
       array to the current vector and call 
       the function with sum = sum-ar[index] and
       index = index, then pop that element from 
       current index (backtrack) and call the 
       function with sum = sum and index = index+1
Below is the C++ implementation of the above steps.
C++
Java
Python3
C#
Javascript
// 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 givenvoid 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 codeint 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 program to find all combinations that// sum to a given valueimport 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 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 Codearr = [2, 4, 6, 8]sum = 8ans = combinationSum(arr, sum) # If result is empty, thenif len(ans) <= 0:    print("empty")     # print all combinations stored in ansfor 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# program for the above approachusing 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
<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, thenif (ans.length == 0) {    document.write("Empty");} // print all combinations stored in ansfor (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>
 ( 2 2 2 2 ) ( 2 2 4 ) ( 2 6 ) ( 4 4 ) ( 8 )
Time Complexity: O(n2), where n is the size of array.
Auxiliary Space: O(n2)
This article is contributed by Aditya Nihal Kumar Singh. 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. 
ss801101
msharma04
ashishrajput1952
rakesh419
NikitaRana07
SHUBHAMSINGH10
girikgarg8
_saurabh_jaiswal
raghav_maheshwari
shivamanandrj9
Adobe
Amazon
Microsoft
Backtracking
Combinatorial
Recursion
Amazon
Microsoft
Adobe
Recursion
Combinatorial
Backtracking
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Generate all the binary strings of N bits
Print all paths from a given source to a destination
Print all permutations of a string in Java
Find if there is a path of more than k length from a source
Permutation and Combination in Python
Factorial of a large number
Count of subsets with sum equal to X
itertools.combinations() module in Python to print all possible combinations
Program to calculate value of nCr