簡體   English   中英

打印數字的所有組合作為候選數字的總和

[英]Print all combinations of a number as a sum of candidate numbers

有人對以下問題有解決方案嗎? 這似乎是一個經典問題,但是我還沒有在網上找到任何好的答案。

給定目標編號和一系列候選編號,請打印出所有組合,以便候選編號的總和等於目標。

此處的順序並不重要,因此請勿打印重復的組合。

例如目標為7,候選為2、3、6、7,輸出應為7和3 + 2 + 2(但不打印2 + 3 + 2、2 + 2 + 3)

由於必須打印所有組合,因此可以使用遞歸使用常規的完整搜索程序。 例如, 此代碼解決了問題,並打印了所有此類組合。

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);
        }
    }
}

使用函數printCombinations的唯一前提條件是數組arr不能包含重復項。 而且,如果其中包含重復項,我們可以使用Set輕松刪除它們。

在代碼中N是必需的目標。 而arr是候選編號的集合。 對於N = 7和arr [] = {2,3,6,7},代碼將輸出:

2 2 3 
7 

看一下使用回溯的代碼。

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);
}

如果候選號碼僅需使用一次,則只需更改第一個遞歸調用並使用“ counter + 1”而不是“ 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);


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM