分析
-
本题的考点:递归回溯。
-
一般由两种搜索顺序:
(1)可以枚举每个位置放置哪个数据;(最常用)
(2)枚举每个数据放置到哪个位置上。
-
这里采用第(1)中搜索方式。
-
另外我们不能选出重复的方案,例如
[1, 2]
和[2, 1]
是同一种方案。假设我们已经将i
放置到位置u
了,我们在第u+1
个位置只能放置[i+1...n]
中的某个元素,即不能向之前的位置搜索,可以通过在dfs
函数中传入起始位置start
即可。
代码
- C++
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
int k;
vector<vector<int>> combine(int n, int _k) {
k = _k;
path.resize(k);
dfs(n, 0, 1);
return ans;
}
// 位置u可以放置[start...]里的数据
void dfs(int n, int u, int start) {
if (u == k) {
ans.push_back(path);
return;
}
for (int i = start; i <= n; i++) {
path[u] = i;
dfs(n, u + 1, i + 1);
}
}
};
- Java
class Solution {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> combine(int n, int k) {
dfs(n, k, 1);
return ans;
}
// 还有u个位置需要放置数据, 和C++代码中的u含义不同, 注意区别
private void dfs(int n, int u, int start) {
if (u == 0) { // 说明path中有k个元素了
ans.add((List<Integer>) path.clone());
return;
}
for (int i = start; i <= n; i++) {
path.add(i);
dfs(n, u - 1, i + 1);
path.removeLast();
}
}
}
时空复杂度分析
-
时间复杂度:指数级别。
-
空间复杂度:和递归深度有关。