按层数思考
全排列我们传入dfs参数是dfs(nums, u); u 代表dfs的层数。dfs每一层我们都要在path数组里加入一个新的元素,并且当前元素可以选择之前的元素。由于每个元素最多只能被添加一次,所以我们要st数组来记录哪些元素已经被使用过,避免元素在当前层被重复添加。
最后判断我们的返回条件可以用 u 到达了 最后一层,或者path数组元素个数满足全排列的元素个数
按遍历的起点思考
每次递归传入参数有三种情况
全排列问题
1. 每次都可以从起点选择元素 (当前元素可以回头看 i = 0 遍历): dfs(nums, startIndex + 1);
组合问题
带重复元素的组合问题
2. 每次只能从当前位置选择元素(当前元素可以选无数次,但是不能往回看):dfs(nums, i);
元素唯一的组合问题
3. 每次只能从下一个位置选择元素(当前元素可以选一次,但是不能往回看):dfs(nums, i + 1);
组合问题一般不传入 startIndex,因为组合是顺序无所谓
i = startIndex 遍历
target = 7
传入 startIndex 和 i 的区别
startIndex 代表每个位置都可以从往前看,并且可以重复利用元素:2,3 -> [2,2,3],[2,3,2],[3,2,2]
传入 i 代表不能往前看但是当前元素可以重复使用:2,3 -> [2,2,3]
Permutation 全排列
全排列代码
class Solution {
public:
vector<vector<int>> res;
vector<bool> st;
vector<int> path;
vector<vector<int>> permute(vector<int>& nums) {
st.assign(nums.size(), false);
dfs(nums, 0);
return res;
}
void dfs(vector<int>& nums, int startIndex) {
if (startIndex == nums.size()) {
res.push_back(path);
return;
}
for (int i = 0; i < nums.size(); i++) {
if (!st[i]) {
path.push_back(nums[i]);
st[i] = true;
dfs(nums, startIndex + 1);
st[i] = false;
path.pop_back();
}
}
}
};