2
头图

Combination Sum II

Title description: Given an array of candidates and a target number target, find out all combinations of candidates that can make the sum of numbers target.

Each number in candidates can only be used once in each combination.

illustrate:

  • All numbers (including the target number) are positive integers.
  • The solution set cannot contain repeated combinations.

Please refer to LeetCode official website for example description.

Source: LeetCode
Link: https://leetcode-cn.com/problems/combination-sum-ii/
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Solution 1: Backtracking algorithm
  • First, sort the original array;
  • Then, declare an array freq to record the number of times each different number appears;
  • Then, the backtracking algorithm is used to recursively judge whether the processed sequence meets the condition, add the sequence that meets the condition to the result set, and finally return all the result set that meets the condition.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class LeetCode_040 {
    /**
     * 记录每个不同的数字出现的次数
     */
    private static List<int[]> freq = new ArrayList<>();
    /**
     * 符合条件的结果集
     */
    private static List<List<Integer>> ans = new ArrayList<>();
    /**
     * 匹配的序列
     */
    private static List<Integer> sequence = new ArrayList<>();

    /**
     * 回溯算法
     *
     * @param candidates
     * @param target
     * @return
     */
    public static List<List<Integer>> combinationSum2(int[] candidates, int target) {
        // 首先将给定的数组排序
        Arrays.sort(candidates);
        for (int num : candidates) {
            int size = freq.size();
            if (freq.isEmpty() || num != freq.get(size - 1)[0]) {
                freq.add(new int[]{num, 1});
            } else {
                ++freq.get(size - 1)[1];
            }
        }
        dfs(0, target);
        return ans;
    }

    public static void dfs(int pos, int rest) {
        if (rest == 0) {
            /**
             * 如果当前的和已经等于target了,将当前的序列添加到结果集
             */
            ans.add(new ArrayList<Integer>(sequence));
            return;
        }
        if (pos == freq.size() || rest < freq.get(pos)[0]) {
            /**
             * 如果已经遍历完所有的数字或者待处理的数小于下一个要匹配的数字,则当前的序列不符合条件,返回
             */
            return;
        }

        dfs(pos + 1, rest);

        int most = Math.min(rest / freq.get(pos)[0], freq.get(pos)[1]);
        for (int i = 1; i <= most; ++i) {
            sequence.add(freq.get(pos)[0]);
            dfs(pos + 1, rest - i * freq.get(pos)[0]);
        }
        for (int i = 1; i <= most; ++i) {
            sequence.remove(sequence.size() - 1);
        }
    }

    public static void main(String[] args) {
        int[] candidates = new int[]{10, 1, 2, 7, 6, 1, 5};
        for (List<Integer> integers : combinationSum2(candidates, 8)) {
            for (Integer integer : integers) {
                System.out.print(integer + " ");
            }
            System.out.println();
        }
    }
}
【Daily Message】 distance is not to be seen by the whole world, but to see the whole world.

醉舞经阁
1.8k 声望7.1k 粉丝

玉树临风,仙姿佚貌!