简体   繁体   中英

Print all combinations of a number as a sum of candidate numbers

Does anyone have a solution to the following question? It seems like a classic problem, but I haven't found any good answers online yet.

Given a target number, and a series of candidate numbers, print out all combinations, so that the sum of candidate numbers equals to the target.

Here order is not important, so don't print the duplicated combination.

eg target is 7, candidate is 2,3,6,7 output should be 7 and 3+2+2 (but not print 2+3+2, 2+2+3)

Since you have to print all the combinations, you can employ a general complete search program using recursion. For example, this code solves the problem and prints all such combinations.

import java.io.*;
import java.math.*;
import java.util.*;

class Solution{ 
    public static void main(String[] args)throws java.lang.Exception{
        new Solution().run();
    }

    int N = 7;
    int[] arr = {2, 3, 6, 7};
    int[] vals = new int[N];;

    void run(){
        printCombinations(N, 0, 0);
    }

    // from : consider numbers in arr from index "from"
    // index: add new number in array vals at index "index"
    void printCombinations(int target, int from, int index){
        if(target==0){
            for(int i=0; i<index; i++){
                System.out.print(vals[i] + " ");
            }
            System.out.println();
        }else if(target<0 || from>=arr.length){
            return;
        }else{
            vals[index] = arr[from];
            // take arr[from] in set
            printCombinations(target-arr[from], from, index+1);

            // dont take arr[from] in set
            printCombinations(target, from+1, index);
        }
    }
}

The only pre condition to using the function printCombinations is that the array arr must not contain duplicates. And if it contains duplicates, we can easily remove them using a Set.

In the code N is required target. And arr is the set of candidate numbers. for N=7 and arr[] = {2, 3, 6, 7} the code prints:

2 2 3 
7 

Have a look at this code which uses backtracking.

public static void main (String[] args) {

    int[] arr = {2,3,6,7};
    int target = 9; 

    ArrayList<Integer> result = new ArrayList<Integer>();

    printCombinations(result, arr, target, 0);
}

private static void printCombinations(ArrayList<Integer> result, int[] arr, int target, int counter) {

    if(target == 0) {
        System.out.println(result);
        return;
    }

    if(target < 0 || counter>=arr.length) {
        return;
    }

    result.add(arr[counter]);
    printCombinations(result, arr, target-arr[counter], counter);

    result.remove(result.indexOf(arr[counter]));
    printCombinations(result, arr, target, counter+1);
}

If the candidate number has to be used only once, then just change the first recursive call and use 'counter+1' instead of 'counter'.

private static void printCombinations(ArrayList<Integer> result, int[] arr, int target, int counter) {

    if(target == 0) {
        System.out.println(result);
        return;
    }

    if(target < 0 || counter>=arr.length) {
        return;
    }

    result.add(arr[counter]);
    printCombinations(result, arr, target-arr[counter], counter+1);

    result.remove(result.indexOf(arr[counter]));
    printCombinations(result, arr, target, counter+1);


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM