排列,用回溯法
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> permutation;
vector<bool> visited(nums.size(), false);
vector<int> vec;
if(nums.size() > 0)
backtrack(permutation, nums, visited, vec, 0);
return permutation;
}
void backtrack(vector<vector<int>>& permutation, const vector<int>& nums, vector<bool>& visited, vector<int>& vec, int start) {
if(nums.size() == start) {
permutation.emplace_back(vec);
return;
}
for(int i = 0; i < nums.size(); ++i) {
if(!visited[i]) {
visited[i] = true;
vec.push_back(nums[i]);
backtrack(permutation, nums, visited, vec, start+1);
visited[i] = false;
vec.pop_back();
}
}
}
};
官方题解没有采用visited数组去判断是否已经排序,采用的是将nums数组分为左右2部分。左边的部分已经排过,右边待排序。每次通过从右边选一个数到左边,来进行回溯
class Solution {
public:
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]);
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > res;
backtrack(res, nums, 0, (int)nums.size());
return res;
}
};