刷刷刷 Day 24 | 77. 组合

77. 组合

LeetCode题目要求

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

解题思路

先理解组合,在本题中,取 [1,4] 范围内的两个数,结果 [2,4] 和 [4,2] 是没有区别的。
组合的根本是穷举,而解决组合问题就是回溯法来实现。
解决问题前,牢记回溯模板

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

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

上代码

class Solution {
    private List<List<Integer>> res = null;
    private Deque<Integer> path = null;
    public List<List<Integer>> combine(int n, int k) {
        res = new ArrayList<>();
        path = new LinkedList<>();
        backtracking(n, k, 1);
        return res;
    }

    private void backtracking(int n, int k, int startIndex) {
        // [1, n]  范围内 k 个数的组合,如 k = 2 ,那么 [1,2] 就是一个结果
        
        // 终止条件
        if (path.size() == k) {
            // 存放结果;
            res.add(new ArrayList<>(path));
            return;
        }

        // 从 startIndex 位置开始,穷举组合, i <= n-(k-path()) + 1  进行了剪枝优化
        for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) {
            // 处理节点;
            path.add(i);
            // 递归
            backtracking(n, k, i + 1); 
            // 回溯,撤销处理结果
            path.removeLast();
        }
    }
}
重难点

重点理解回溯方法,记住回溯模板,及剪枝优化

附:学习资料链接

posted @ 2023-01-27 23:34  blacksonny  阅读(13)  评论(0编辑  收藏  举报