繁体   English   中英

给定一个数字和一个数组,找出总和为给定数字的所有可能组合

[英]Given a number and an array find all possible combinations that sum up to given number

我在一次采访中被问到这个项目。 任务给出一个整数数组作为输入,另一个数字说target ,在数组中找到所有可能的组合,这些组合总和为给定的目标。

例子:

array = [1,2,1,1,1]
target = 3

expected result : [1,2],[1,1,1],[2,1],[2,1]

我想出了以下代码:

public static void main(String args[]) {
    Integer[] numbers = { 1, 2, 1, 1, 1 };
    int target = 3;
    process(numbers, target);
}

private static void process(Integer[] numbers, int target) {
    for (int i = 0; i < numbers.length; i++) {
        int sum = 0;

        for (int j = i; j < numbers.length; j++) {
            sum += numbers[j];
            if (sum == target) {
                for (int k = i; k <= j; k++) {
                    System.out.print(numbers[k] + " ");
                }
                System.out.println();
            }
        }
    }
}

但此代码仅打印 3 种组合: [1 2], [2 1], [1 1 1]

这样做的正确方法是什么? 有没有其他更好的解决方案。

你可以使用回溯来做这样的事情:

  public List<List<Integer>> combinationSum(int[] candidates, int target) {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> temp = new ArrayList<>();
    Arrays.sort(candidates);
    int start = 0; 

    backtrack(candidates, target, start, result, temp);

    return result;
}

public void backtrack(int[] candidates, int remaining, int start, List<List<Integer>> result, List<Integer> temp) {
    if(remaining == 0) { 
        result.add(new ArrayList<>(temp)); 
        return;
    }

    if(remaining < 0) { return; }

    for(int i = start; i < candidates.length; i++) {
        temp.add(candidates[i]);
        backtrack(candidates, remaining - candidates[i], i, result, temp);
        temp.remove(temp.size() - 1);
    }
}

您可以阅读有关回溯和类似方法的更多信息。

这是使用递归的绝佳候选者:

public static void main(String args[]) {
    Integer[] numbers = { 1, 2, 1, 1, 1 };
    int target = 3;

    for(int i = 0; i < numbers.length; i++) {
        recurseAdd(i, numbers, new ArrayList<Integer>(), 0, target);
    }
}

private static void recurseAdd(int currentIndex, Integer[] numbers, List<Integer> usedNumbers, int sum, int target) {
    if (currentIndex >= numbers.length) {
        return;
    }

    sum = sum + numbers[currentIndex];
    usedNumbers.add(numbers[currentIndex]);

    if (sum == target) {
        System.out.println(usedNumbers);
        return;
    }

    if (sum > target) {
        return;
    }

   for (int i = currentIndex + 1; i < numbers.length; i++) {
        recurseAdd(i, numbers, new ArrayList<>(usedNumbers), sum, target);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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