2021.09.26 - 085.组合

1. 题目

在这里插入图片描述

2. 思路

(1) 递归

  • 递归的两大核心:
    1. 终止条件。这道题的终止条件有两个:当k=1时,返回1个包含n个数的集合;当n=k时,返回n个包含1个数的集合。
    2. f(n)与f(n-1)的关系。这道题从n个数中找出k个数的组合,其结果分成两部分:一部分是从n-1个数中找出k个数的组合,另一部分是先从n-1个数中找出k-1个数的组合,然后每个组合都加入n,最后合并两个部分,即可得到结果。
  • 一般是从后往前推导,先找终止条件,然后找f(n)与f(n-1)的关系,在f(n-1)的结果上进行加工得到f(n)的结果。

(2) DFS+剪枝策略

  • 参考二叉树的深度优先搜索,利用移除最后一个元素实现回溯。

(3) 字典序法

  • 复杂且低效。

3. 代码

import java.util.ArrayList;
import java.util.List;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Solution solution = new Solution();
        System.out.println(solution.combine(4, 2));
    }
}

class Solution {
    
    
    public List<List<Integer>> combine(int n, int k) {
    
    
        List<List<Integer>> res;
        List<Integer> temp;
        if (k == 1) {
    
    
            res = new ArrayList<>();
            for (int i = 1; i <= n; i++) {
    
    
                temp = new ArrayList<>();
                temp.add(i);
                res.add(temp);
            }
            return res;
        }
        if (n == k) {
    
    
            res = new ArrayList<>();
            temp = new ArrayList<>();
            for (int i = 1; i <= n; i++) {
    
    
                temp.add(i);
            }
            res.add(temp);
            return res;
        }
        res = combine(n - 1, k);
        List<List<Integer>> sub = combine(n - 1, k - 1);
        for (int i = 0; i < sub.size(); i++) {
    
    
            sub.get(i).add(n);
            res.add(sub.get(i));
        }
        return res;
    }
}

class Solution1 {
    
    
    private List<List<Integer>> res = new ArrayList<>();
    private List<Integer> temp = new ArrayList<>();

    public List<List<Integer>> combine(int n, int k) {
    
    
        dfs(1, n, k);
        return res;
    }

    private void dfs(int cur, int n, int k) {
    
    
        if (temp.size() + (n - cur + 1) < k) {
    
    
            return;
        }
        if (temp.size() == k) {
    
    
            res.add(new ArrayList<>(temp));
            return;
        }
        temp.add(cur);
        dfs(cur + 1, n, k);
        temp.remove(temp.size() - 1);
        dfs(cur + 1, n, k);
    }
}

class Solution2 {
    
    
    public List<List<Integer>> combine(int n, int k) {
    
    
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> temp = new ArrayList<>();
        for (int i = 1; i <= k; i++) {
    
    
            temp.add(i);
        }
        temp.add(n + 1);
        int j = 0;
        while (j < k) {
    
    
            res.add(new ArrayList<>(temp.subList(0, k)));
            j = 0;
            while (j < k && temp.get(j) + 1 == temp.get(j + 1)) {
    
    
                temp.set(j, j + 1);
                j++;
            }
            temp.set(j, temp.get(j) + 1);
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_44021223/article/details/120484041
今日推荐