39 Combined sum (dfs)

1. Problem description:

Given an array of candidates without repeating elements and a target number target, find all combinations of candidates that can make the number sum target.

The numbers in candidates can be selected repeatedly without restriction.

Description:

All numbers (including target) are positive integers.
The solution set cannot contain duplicate combinations. 
Example 1:

Input: candidates = [2,3,6,7], target = 7,
the solved set is:
[
  [7],
  [2,2,3]
]
Example 2:

Input: candidates = [2,3,5], target = 8,
the solved set is:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

Source: LeetCode
link: https://leetcode-cn.com/problems/combination-sum

2. Thinking analysis:

① It can be seen from the title that there is an obvious feature. In the process of making up the target number, it is actually trying to try possible solutions. For example, in the first test case, the target number is 7 and one of them is two 2 and one. 3 But we ca n’t really estimate how many 2s and 3s to use or to estimate it is difficult to use conventional methods to solve, and dfs can solve this problem, because dfs is the most suitable for this kind of problem. Under the circumstances, try one by one possible solutions until the target number is reached or all recursive methods are executed, so it is very appropriate to use dfs to solve

② For dfs to solve, we can first draw a picture and describe the process of recursion. This is similar to the recursive traversal of a binary tree. The following is a picture drawn using Word (very rough and simple, and some remaining ones are not drawn) , The purpose of drawing a recursive tree is to better understand the entire process and can clearly determine the value of some parameters in the recursive method. This problem because the requirements cannot be repeated, so if we recursively in the loop, we need to loop variables Start from the current position instead of starting from zero, because I can only add the number of my position and the number after my position so that the result obtained is not repeated. If you start from zero, then the results are often repeated , So when passing the recursive position, you need to pass the current position in the past. This can be combined with the recursive tree to understand a little better

③ Because recursion is time-consuming, it needs to be pruned in advance. We can sort the array at the beginning, so that recursion in the loop can be judged in advance, for example, when it is found that the current position is added After the value is too large, it can be broken, because the number behind is larger

④ You can use the stack or double-ended queue to store the intermediate process. If you use the stack to store, you can add the elements of the stack to the ArrayList. Do not use List to store the intermediate process, because when the List adds elements If there is a modification later, the elements in the List will also change. If you need to use List, you need to traverse the List at the recursive exit and use another List to add these elements. In general, it is best to use the stack or double-ended queue to process The process of getting the target number in the middle

3. The code is as follows:

import java.util.*;
public class Solution {
    List<List<Integer>> res = new ArrayList<>();
    int len = 0;
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        /*先要对数组进行排序可以减少时间复杂度*/
        Arrays.sort(candidates);
        len = candidates.length;
        recursion(candidates, target, 0, 0, new Stack());
        return res;
    }

    /*第三个参数是之前各个元素的累加和, 第四个参数表示的是当前递归的位置*/
    private void recursion(int[] candidates, int target, int cur, int pos, Stack stack) {
        if (cur == target) {
            res.add(new ArrayList<>(stack));
            return;
        }
        for (int i = pos; i < len; ++i){
            /*剪枝, 当前元素都大于了target肯定之后的元素更是加起来大于了target这个剪枝对于提升效率是很有帮助的*/
            if (cur + candidates[i] > target) break;
            stack.add(candidates[i]);
            recursion(candidates, target, cur + candidates[i], i, stack);
            /*回溯*/
            stack.pop();
        }
    }
}

 

Published 569 original articles · Like 153 · Visits 590,000+

Guess you like

Origin blog.csdn.net/qq_39445165/article/details/105396709