1. question: 组合(中等)
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/combinations
示例 1:
1 | 输入:n = 4, k = 2 |
示例 2:
1 | 输入:n = 1, k = 1 |
提示:
1 | 1 <= n <= 20 |
2. answers
这道题,第一次做回溯算法,参考的题解。回溯算法的要点有两个:1. 将问题抽象成树形结构;2. 回溯销毁上一次的结果。
这道题是组合问题,回想高中的知识点:从n个数中选取k个数,第一个数有 n- k + 1个选择(因为要保证后续至少有n-1个数可选择),第二个数肯定不能包含第一个数,一定是要在第一个数的后一个数开始选择,所以它有(n-1) - (k-1) + 1个选择,第三个数则有(n-2) - (k-2) + 1个选择,以此类推。
因此,其实上面的步骤就已经将所有的选择筛选出来了,但是如何遍历呢?每个数有多个选择,那么就循环每一个选择,之后,以递归的形式进行进行下个数的选择。那么什么时候递归结束呢?构造出k个数即可。
递归构造出k个数之后,将其添加到结果中,之后,删除k个数的最后一个数,递归返回到上一步,继续遍历,这就是回溯。
1 | public class Solution_0078_02 { |
可以将回溯法看成是树形结构,节点就是每个数,叶子节点就是每个集合中的最后一个数,遍历到每个叶子节点即可。
另外,确实可以发现,回溯是递归的副产品,也就是在递归的基础上,撤销上一步的操作。但是迭代是不是也能实现回溯呢?有待考证。感觉应该也可以,因为迭代既然能生成所有结果,也应该能返回上一步的操作。
3. 备注
参考力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 (leetcode-cn.com),代码随想录 (programmercarl.com)。