Description# Given two integers n
and k
, return all possible combinations of k
numbers chosen from the range [1, n]
.
You may return the answer in any order .
Example 1:
Input: n = 4, k = 2
Output: [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
Explanation: There are 4 choose 2 = 6 total combinations.
Note that combinations are unordered, i.e., [1,2] and [2,1] are considered to be the same combination.
Example 2:
Input: n = 1, k = 1
Output: [[1]]
Explanation: There is 1 choose 1 = 1 total combination.
Constraints:
Solutions# Solution 1: Backtracking (Two Ways)# We design a function d f s ( i ) dfs(i) df s ( i ) , which represents starting the search from number i i i , with the current search path as t t t , and the answer as a n s ans an s .
The execution logic of the function d f s ( i ) dfs(i) df s ( i ) is as follows:
If the length of the current search path t t t equals k k k , then add the current search path to the answer and return. If i > n i \gt n i > n , it means the search has ended, return. Otherwise, we can choose to add the number i i i to the search path t t t , and then continue the search, i.e., execute d f s ( i + 1 ) dfs(i + 1) df s ( i + 1 ) , and then remove the number i i i from the search path t t t ; or we do not add the number i i i to the search path t t t , and directly execute d f s ( i + 1 ) dfs(i + 1) df s ( i + 1 ) . The above method is actually enumerating whether to select the current number or not, and then recursively searching the next number. We can also enumerate the next number j j j to be selected, where i ≤ j ≤ n i \leq j \leq n i ≤ j ≤ n . If the next number to be selected is j j j , then we add the number j j j to the search path t t t , and then continue the search, i.e., execute d f s ( j + 1 ) dfs(j + 1) df s ( j + 1 ) , and then remove the number j j j from the search path t t t .
In the main function, we start the search from number 1 1 1 , i.e., execute d f s ( 1 ) dfs(1) df s ( 1 ) .
The time complexity is ( C n k × k ) (C_n^k \times k) ( C n k × k ) , and the space complexity is O ( k ) O(k) O ( k ) . Here, C n k C_n^k C n k represents the combination number.
Similar problems:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution :
def combine ( self , n : int , k : int ) -> List [ List [ int ]]:
def dfs ( i : int ):
if len ( t ) == k :
ans . append ( t [:])
return
if i > n :
return
t . append ( i )
dfs ( i + 1 )
t . pop ()
dfs ( i + 1 )
ans = []
t = []
dfs ( 1 )
return ans
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
private List < List < Integer >> ans = new ArrayList <> ();
private List < Integer > t = new ArrayList <> ();
private int n ;
private int k ;
public List < List < Integer >> combine ( int n , int k ) {
this . n = n ;
this . k = k ;
dfs ( 1 );
return ans ;
}
private void dfs ( int i ) {
if ( t . size () == k ) {
ans . add ( new ArrayList <> ( t ));
return ;
}
if ( i > n ) {
return ;
}
t . add ( i );
dfs ( i + 1 );
t . remove ( t . size () - 1 );
dfs ( i + 1 );
}
}
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public :
vector < vector < int >> combine ( int n , int k ) {
vector < vector < int >> ans ;
vector < int > t ;
function < void ( int ) > dfs = [ & ]( int i ) {
if ( t . size () == k ) {
ans . emplace_back ( t );
return ;
}
if ( i > n ) {
return ;
}
t . emplace_back ( i );
dfs ( i + 1 );
t . pop_back ();
dfs ( i + 1 );
};
dfs ( 1 );
return ans ;
}
};
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func combine ( n int , k int ) ( ans [][] int ) {
t := [] int {}
var dfs func ( int )
dfs = func ( i int ) {
if len ( t ) == k {
ans = append ( ans , slices . Clone ( t ))
return
}
if i > n {
return
}
t = append ( t , i )
dfs ( i + 1 )
t = t [: len ( t ) - 1 ]
dfs ( i + 1 )
}
dfs ( 1 )
return
}
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function combine ( n : number , k : number ) : number [][] {
const ans : number [][] = [];
const t : number [] = [];
const dfs = ( i : number ) => {
if ( t . length === k ) {
ans . push ( t . slice ());
return ;
}
if ( i > n ) {
return ;
}
t . push ( i );
dfs ( i + 1 );
t . pop ();
dfs ( i + 1 );
};
dfs ( 1 );
return ans ;
}
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
impl Solution {
fn dfs ( i : i32 , n : i32 , k : i32 , t : & mut Vec < i32 > , ans : & mut Vec < Vec < i32 >> ) {
if t . len () == ( k as usize ) {
ans . push ( t . clone ());
return ;
}
if i > n {
return ;
}
t . push ( i );
Self ::dfs ( i + 1 , n , k , t , ans );
t . pop ();
Self ::dfs ( i + 1 , n , k , t , ans );
}
pub fn combine ( n : i32 , k : i32 ) -> Vec < Vec < i32 >> {
let mut ans = vec! [];
Self ::dfs ( 1 , n , k , & mut vec! [], & mut ans );
ans
}
}
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Solution {
private List < IList < int >> ans = new List < IList < int >>();
private List < int > t = new List < int >();
private int n ;
private int k ;
public IList < IList < int >> Combine ( int n , int k ) {
this . n = n ;
this . k = k ;
dfs ( 1 );
return ans ;
}
private void dfs ( int i ) {
if ( t . Count == k ) {
ans . Add ( new List < int >( t ));
return ;
}
if ( i > n ) {
return ;
}
t . Add ( i );
dfs ( i + 1 );
t . RemoveAt ( t . Count - 1 );
dfs ( i + 1 );
}
}
copy
Solution 2# 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution :
def combine ( self , n : int , k : int ) -> List [ List [ int ]]:
def dfs ( i : int ):
if len ( t ) == k :
ans . append ( t [:])
return
if i > n :
return
for j in range ( i , n + 1 ):
t . append ( j )
dfs ( j + 1 )
t . pop ()
ans = []
t = []
dfs ( 1 )
return ans
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
private List < List < Integer >> ans = new ArrayList <> ();
private List < Integer > t = new ArrayList <> ();
private int n ;
private int k ;
public List < List < Integer >> combine ( int n , int k ) {
this . n = n ;
this . k = k ;
dfs ( 1 );
return ans ;
}
private void dfs ( int i ) {
if ( t . size () == k ) {
ans . add ( new ArrayList <> ( t ));
return ;
}
if ( i > n ) {
return ;
}
for ( int j = i ; j <= n ; ++ j ) {
t . add ( j );
dfs ( j + 1 );
t . remove ( t . size () - 1 );
}
}
}
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public :
vector < vector < int >> combine ( int n , int k ) {
vector < vector < int >> ans ;
vector < int > t ;
function < void ( int ) > dfs = [ & ]( int i ) {
if ( t . size () == k ) {
ans . emplace_back ( t );
return ;
}
if ( i > n ) {
return ;
}
for ( int j = i ; j <= n ; ++ j ) {
t . emplace_back ( j );
dfs ( j + 1 );
t . pop_back ();
}
};
dfs ( 1 );
return ans ;
}
};
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func combine ( n int , k int ) ( ans [][] int ) {
t := [] int {}
var dfs func ( int )
dfs = func ( i int ) {
if len ( t ) == k {
ans = append ( ans , slices . Clone ( t ))
return
}
if i > n {
return
}
for j := i ; j <= n ; j ++ {
t = append ( t , j )
dfs ( j + 1 )
t = t [: len ( t ) - 1 ]
}
}
dfs ( 1 )
return
}
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function combine ( n : number , k : number ) : number [][] {
const ans : number [][] = [];
const t : number [] = [];
const dfs = ( i : number ) => {
if ( t . length === k ) {
ans . push ( t . slice ());
return ;
}
if ( i > n ) {
return ;
}
for ( let j = i ; j <= n ; ++ j ) {
t . push ( j );
dfs ( j + 1 );
t . pop ();
}
};
dfs ( 1 );
return ans ;
}
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
impl Solution {
fn dfs ( i : i32 , n : i32 , k : i32 , t : & mut Vec < i32 > , ans : & mut Vec < Vec < i32 >> ) {
if t . len () == ( k as usize ) {
ans . push ( t . clone ());
return ;
}
if i > n {
return ;
}
for j in i ..= n {
t . push ( j );
Self ::dfs ( j + 1 , n , k , t , ans );
t . pop ();
}
}
pub fn combine ( n : i32 , k : i32 ) -> Vec < Vec < i32 >> {
let mut ans = vec! [];
Self ::dfs ( 1 , n , k , & mut vec! [], & mut ans );
ans
}
}
copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Solution {
private List < IList < int >> ans = new List < IList < int >>();
private List < int > t = new List < int >();
private int n ;
private int k ;
public IList < IList < int >> Combine ( int n , int k ) {
this . n = n ;
this . k = k ;
dfs ( 1 );
return ans ;
}
private void dfs ( int i ) {
if ( t . Count == k ) {
ans . Add ( new List < int >( t ));
return ;
}
if ( i > n ) {
return ;
}
for ( int j = i ; j <= n ; ++ j ) {
t . Add ( j );
dfs ( j + 1 );
t . RemoveAt ( t . Count - 1 );
}
}
}
copy