class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>>res;
backtrack(res, nums, 0, nums.size());
return res;
}
void backtrack(vector<vector<int>>&res,vector<int>&output, int first,int len){
//所有的数都填满了
if(first == len){
res.emplace_back(output);
return;
}
for(int i = first; i < len; i++){
//动态维护数组
swap(output[i], output[first]);
//继续递归填下一个数
backtrack(res, output, first+1, len);
//撤销操作
swap(output[i], output[first]);
}
}
};
dfs+回溯
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
int n = nums.size();
vector<vector<int>>res;
vector<int>temp;
vector<bool>used(n,false);
dfs(res,temp,nums,used,n);
return res;
}
void dfs(vector<vector<int>>&res, vector<int>&temp, vector<int>&nums, vector<bool>&used,int n){
if(temp.size() == n){
res.push_back(temp);
}
// 在非叶子结点处,产生不同的分支,这一操作的语义是:在还未选择的数中依次选择一个元素作为下一个位置的元素,这显然得通过一个循环实现。
for(int i = 0; i < n; i++){
if(!used[i]){
temp.push_back(nums[i]);
used[i] = true;
dfs(res,temp,nums,used,n);
// 注意:下面这两行代码发生 「回溯」,回溯发生在从 深层结点 回到 浅层结点 的过程,代码在形式上和递归之前是对称的
temp.pop_back();
used[i] = false;
}
}
}
};