【问题描述】[中等]
【解答思路】
1. 回溯
class Solution {List<List<Integer>> lists = new ArrayList<>();public List<List<Integer>> combine(int n, int k) {List<Integer> list = new ArrayList<>();backTrace(list, n, k, 0);return lists;}private void backTrace(List<Integer>list, int n, int k, int depth){if(depth>k){return ;}if(depth == k){lists.add(new ArrayList<>(list));return;}for(int i = 1;i<=n ; i++){list.add(i);backTrace(list, n, k, depth+1);list.remove(list.size()-1);}}
}
2. 回溯优化
分析搜索起点的上界进行剪枝
class Solution {List<List<Integer>> lists = new ArrayList<>();public List<List<Integer>> combine(int n, int k) {List<Integer> list = new ArrayList<>();backTrace(list, n, k, 0);return lists;}private void backTrace(List<Integer>list, int n, int k, int depth){if(depth>k){return ;}if(depth == k){lists.add(new ArrayList<>(list));return;}
// 只有这里 i <= n - (k - path.size()) + 1 与参考代码 1 不同for(int i = 1;i <= n - (k - path.size()) + 1 ; i++){list.add(i);backTrace(list, n, k, depth+1);list.remove(list.size()-1);}}
}
【总结】
1. 回溯法解决组合问题。和排列问题不同的是,在组合问题中元素的顺序不考虑,只需要从当前位置向后寻找。排列问题每次都需要从头寻找,需要用visited数组记录访问过的元素。
2.相关题目
[Leedcode][JAVA][第46题][全排列][回溯算法]
[Leetcode][第81题][JAVA][N皇后问题][回溯算法]
[Leetcode][第60题][JAVA][第k个排列][回溯][DFS][剪枝]
转载:https://leetcode-cn.com/problems/combinations/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-ma-/