Day20 | 77组合&17电话号码的字母组合&39组合总和&40组合总和 II&216组合总和 III

40 阅读2分钟

组合 LeetCode 77

题目链接:[LeetCode 77 - 中等]

思路

参数:void backtracking(int n, int k,int index) for(int i=index;i<=n;i++)

回溯:

class Solution {
    List<List<Integer>> resList = new ArrayList<>();
    LinkedList<Integer> res = new LinkedList<>();
    public List<List<Integer>> combine(int n, int k) {
        backtracking(n,k,1);
        return resList;
    }
    private void backtracking(int n, int k,int index){
        if(res.size() == k){
            resList.add(new ArrayList<>(res));
            return;
        }
        for(int i=index;i<=n;i++){
            res.add(i);
            backtracking(n,k,i+1);
            res.removeLast();
        }
    }
}

回溯的模板

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

优化方式:

int i=index;i<=n-(k-res.size())+1;i++

电话号码的字母组合 LeetCode 17

题目链接:[LeetCode 17 - 中等]

思路

使用StringBuilder和回溯。

回溯:

class Solution {
    List<String> res = new ArrayList<>();
    String[] digit = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    StringBuilder sb = new StringBuilder();
    public List<String> letterCombinations(String digits) {
        if(digits==null || digits.length()==0)return res;
        backtracing(digits,0);
        return res;
    }
    private void backtracing(String digits,int num){
        if(num == digits.length()){
            res.add(sb.toString());
            return;
        }
        String str = digit[digits.charAt(num)-'0'];
        for(int i=0;i<str.length();i++){
            sb.append(str.charAt(i));
            backtracing(digits,num+1);
            sb.deleteCharAt(sb.length()-1);
        }
    }
}

组合总和 LeetCode 39

题目链接:[LeetCode 39 - 中等]

思路

可以考虑到无限制重复被选用。 所以在循环的时候可以使用index。

回溯:

class Solution {
    List<List<Integer>> resList = new ArrayList<>();
    LinkedList<Integer> res = new LinkedList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        backtracking(0,target,0,candidates);
        return resList;
    }
    private void backtracking(int sum,int target,int index,int[] candidates){
        if(sum==target){
            resList.add(new ArrayList(res));
            return;
        }else if(sum>target){
            return;
        }
        for(int i=index;i<candidates.length;i++){
            sum+=candidates[i];
            res.add(candidates[i]);
            backtracking(sum,target,i,candidates);
            res.removeLast();
            sum-=candidates[i];
        }
    }
}

组合总和 II LeetCode 40

题目链接:[LeetCode 40 - 中等]

思路

回溯:

class Solution {
    List<List<Integer>> resList = new ArrayList<>();
    LinkedList<Integer> res = new LinkedList<>();
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        backtracking(0,target,0,candidates);
        return resList;
    }
    private void backtracking(int sum,int target,int index,int[] candidates){
        if(sum==target){
            resList.add(new ArrayList(res));
            return;
        }else if(sum>target){
            return;
        }
        for(int i=index;i<candidates.length;i++){
            if(i>index && candidates[i]==candidates[i-1])continue;
            sum+=candidates[i];
            res.add(candidates[i]);
            backtracking(sum,target,i+1,candidates);
            res.removeLast();
            sum-=candidates[i];
        }
    }
}

组合总和 III LeetCode 216

题目链接:[LeetCode 216 - 中等]

思路

思路不难找,和之前差不多。

回溯:

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> res = new LinkedList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        backtracing(k,n,1,0);
        return result;
    }
    private void backtracing(int k,int n,int index,int sum){
        if(sum == n && res.size() == k ){
            result.add(new ArrayList(res));
            return;
        }
        for(int i=index;i<=9;i++){
            if(sum > n) continue;
            sum += i;
            res.add(i);
            backtracing(k,n,i+1,sum);
            res.removeLast();
            sum -= i;
        }
    }
}