Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
这道题与permutations稍有不同,将permutations那道题的代码稍加改动可以得到全排列组合,有些会重复,比如[2, 1]和[1, 2],所以这道题要加一个start,用于初始for循环i的起始条件。这样递归后就不会出现重复了。 另外 visited数组在这道题中没什么用处,去掉后只需将searchNum的传参中的i改为i+1即可(参见Source2)。
Source
public class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> st = new ArrayList<List<Integer>>();
List<Integer> a = new ArrayList<Integer>();
if(n == 0 || k == 0) return st;
int start = 1;
boolean[] visited = new boolean[n + 1];
searchNum(start, n, k, st, a, visited);
return st;
}
public void searchNum(int start, int n, int k, List<List<Integer>> st, List<Integer> a, boolean[] visited){
if(a.size() == k){
st.add(new ArrayList<Integer>(a)); //注意递归时的st添加要为a新分配空间
return;
}
for(int i = start; i <= n; i++){
if(!visited[i]){
a.add(i);
visited[i] = true;
searchNum(i, n, k, st, a, visited);
a.remove(a.size() - 1); //remove***
visited[i] = false;
}
}
}
}
Test
public static void main(String[] args){
int n = 4, k = 2;
System.out.println(new Solution().combine(n, k));
}
Source
public class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> st = new ArrayList<List<Integer>>();
List<Integer> a = new ArrayList<Integer>();
if(n == 0 || k == 0) return st;
int start = 1;
//boolean[] visited = new boolean[n + 1];
searchNum(start, n, k, st, a);
return st;
}
public void searchNum(int start, int n, int k, List<List<Integer>> st, List<Integer> a){
if(a.size() == k){
st.add(new ArrayList<Integer>(a)); //注意递归时的st添加要为a新分配空间
return;
}
for(int i = start; i <= n; i++){
// if(!visited[i]){
a.add(i);
// visited[i] = true;
searchNum(i + 1, n, k, st, a);
a.remove(a.size() - 1); //remove***
// visited[i] = false;
// }
}
}
}