77. 组合
方法一:根据搜索起点画出二叉树
public List < List < Integer > > combine ( int n, int k) {
List < List < Integer > > res = new ArrayList < > ( ) ;
if ( k <= 0 || n < k) {
return res;
}
Deque < Integer > path = new ArrayDeque < > ( ) ;
dfs ( n, k, 1 , path, res) ;
return res;
}
private void dfs ( int n, int k, int begin, Deque < Integer > path, List < List < Integer > > res) {
if ( path. size ( ) == k) {
res. add ( new ArrayList < > ( path) ) ;
return ;
}
for ( int i = begin; i <= n; i++ ) {
path. addLast ( i) ;
dfs ( n, k, i + 1 , path, res) ;
path. removeLast ( ) ;
}
}
优化:分析搜索起点的上界进行剪枝
public List < List < Integer > > combine ( int n, int k) {
List < List < Integer > > res = new ArrayList < > ( ) ;
if ( k <= 0 || n < k) {
return res;
}
Deque < Integer > path = new ArrayDeque < > ( ) ;
dfs ( n, k, 1 , path, res) ;
return res;
}
private void dfs ( int n, int k, int begin, Deque < Integer > path, List < List < Integer > > res) {
if ( path. size ( ) == k) {
res. add ( new ArrayList < > ( path) ) ;
return ;
}
for ( int i = begin; i <= n - ( k - path. size ( ) ) + 1 ; i++ ) {
path. addLast ( i) ;
dfs ( n, k, i + 1 , path, res) ;
path. removeLast ( ) ;
}
}
方法二:按照每一个数选与不选画出二叉树
public List < List < Integer > > combine ( int n, int k) {
List < List < Integer > > res = new ArrayList < > ( ) ;
if ( k <= 0 || n < k) {
return res;
}
Deque < Integer > path = new ArrayDeque < > ( k) ;
dfs ( 1 , n, k, path, res) ;
return res;
}
private void dfs ( int begin, int n, int k, Deque < Integer > path, List < List < Integer > > res) {
if ( k == 0 ) {
res. add ( new ArrayList < > ( path) ) ;
return ;
}
if ( begin > n - k + 1 ) {
return ;
}
dfs ( begin + 1 , n , k, path , res) ;
path. addLast ( begin) ;
dfs ( begin + 1 , n, k - 1 , path, res) ;
path. removeLast ( ) ;
}