给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
示例 1:
输入:n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
示例 2:
输入:n = 1, k = 1 输出:[[1]]
提示:
1 <= n <= 20 1 <= k <= n
解题思路:
1.每个元素有选与不选两种情况,
2.回溯能将选与不选这两种情况都包含
3.递归刚好能满足这个需求
dfs + 回溯代码:
class Solution {
public List < List < Integer > > combine ( int n, int k) {
List < List < Integer > > end = new ArrayList < > ( ) ;
List < Integer > mb = new ArrayList < > ( ) ;
addmbzh ( 1 , k, end, mb, n) ;
return end;
}
public static void addmbzh ( int x, int k, List < List < Integer > > end, List < Integer > none, int n) {
if ( x > n + 1 ) return ;
if ( none. size ( ) == k) {
end. add ( new ArrayList < Integer > ( none) ) ;
return ;
}
none. add ( x) ;
addmbzh ( x + 1 , k, end, none, n) ;
none. remove ( none. size ( ) - 1 ) ;
addmbzh ( x + 1 , k, end, none, n) ;
}
}
可以出上述递归树,有很多没有用的分支,可以加入特定判断条件将无用分支剪切掉
if(none.size() + n - x + 1 < k) return;//即剩下元素不足,直接退出
dfs + 回溯 + 剪枝:
class Solution {
public List < List < Integer > > combine ( int n, int k) {
List < List < Integer > > end = new ArrayList < > ( ) ;
List < Integer > mb = new ArrayList < > ( ) ;
addmbzh ( 1 , k, end, mb, n) ;
return end;
}
public static void addmbzh ( int x, int k, List < List < Integer > > end, List < Integer > none, int n) {
if ( none. size ( ) + n - x + 1 < k) return ;
if ( none. size ( ) == k) {
end. add ( new ArrayList < Integer > ( none) ) ;
return ;
}
none. add ( x) ;
addmbzh ( x + 1 , k, end, none, n) ;
none. remove ( none. size ( ) - 1 ) ;
addmbzh ( x + 1 , k, end, none, n) ;
}
}
不难看出爆搜会超时的主要原因是一些无用枝节耗费了大量时间
本代码也可以用全局变量来写,反而更简洁
代码:
class Solution {
List < List < Integer > > nums = new ArrayList < > ( ) ;
List < Integer > num = new ArrayList < > ( ) ;
public List < List < Integer > > combine ( int n, int k) {
dfs ( 1 , n, k) ;
return nums;
}
public void dfs ( int i, int n, int k) {
if ( num. size ( ) + n - i + 1 < k) return ;
if ( num. size ( ) == k) {
nums. add ( new ArrayList < Integer > ( num) ) ;
return ;
}
num. add ( i) ;
dfs ( i + 1 , n, k) ;
num. remove ( num. size ( ) - 1 ) ;
dfs ( i + 1 , n, k) ;
}
}