Combinations
Combinations
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],
]
及从1到n中选出k个数,得到所有的结果。题目中没有刻意强调升序。
开始想到的是动态规划,后一个数依赖前面的数字。具体实现如下。
public class Solution {
public List<List<Integer>> combine(int n, int k) {
if (k > n)
return null;
else {
List<List<Integer>> result = new ArrayList<List<Integer>>();
List<List<Integer>> resultSwitch = new ArrayList<List<Integer>>();
for (int i1 = 0; i1 < k; i1++) {
if (i1 == 0) {
for (int i2 = 1; i2 <= n - k + 1; i2++) {
List<Integer> temp = new ArrayList<Integer>();
temp.add(i2);
result.add(temp);
}
} else {
while (result.size() != 0) {
List<Integer> temp = result.get(0);
for (int i = temp.get(temp.size() - 1) + 1; i <= n - k + temp.size() + 1; i++) {
List<Integer> tempClone = this.clone(temp);
tempClone.add(i);
resultSwitch.add(tempClone);
}
result.remove(0);
}
List<List<Integer>> temp = result;
result = resultSwitch;
resultSwitch = temp;
}
}
return result;
}
}
private List<Integer> clone(List<Integer> source) {
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < source.size(); i++) {
result.add(source.get(i));
}
return result;
}
}
后来在网上看到dfs深度优先搜寻,代码更简洁。
public class Solution {
public List<List<Integer>> combine(int n, int k) {
if (k > n)
return null;
else {
List<List<Integer>> result = new ArrayList<List<Integer>>();
List<Integer> rs = new ArrayList<Integer>();
this.dfs(n, k, rs, result);
return result;
}
}
private void dfs(int n, int k, List<Integer> rs, List<List<Integer>> result) {
if (k == 0) {
result.add(rs);
return;
} else {
for (int i = rs.size() == 0 ? 1 : rs.get(rs.size() - 1) + 1; i <= n - k + 1; i++) {
List<Integer> tempList = this.clone(rs);
tempList.add(i);
this.dfs(n, k - 1, tempList, result);
}
}
}
private List<Integer> clone(List<Integer> source) {
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < source.size(); i++) {
result.add(source.get(i));
}
return result;
}
}