给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
法一:递归
固定第一个数,对剩余的进行同样的算法,然后把第一个数在每个位置差进去,形成新的排列
效率:9.48%
由于递归过程中有大量的拷贝,所以效率非常低
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums, int loc) {
vector<vector<int>> res;
if (loc == nums.size() - 1) {
vector<int> t(1, nums[loc]);
res.push_back(t);
return res;
}
else {
int now = nums[loc];
vector<vector<int>> back = permute(nums, loc + 1);
vector<vector<int>> res;
for (int i = 0; i < back.size(); i++) {
for(int j = 0; j < nums.size() - loc; j++) {
vector<int> t = back[i];
t.insert(t.begin() + j,now);
res.push_back(t);
}
}
return res;
}
}
vector<vector<int>> permute(vector<int>& nums) {
return permute(nums, 0);
}
};
法二:和法一差不多,不同的是第一个数不插进去,而是放到最后,然后和每个位置的数交换,形成新的排列
效率:13.20%
由于仍然有拷贝,所以效率不高
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums, int loc) {
vector<vector<int>> res;
if (loc == nums.size() - 1) {
vector<int> t(1, nums[loc]);
res.push_back(t);
return res;
}
else {
int now = nums[loc];
vector<vector<int>> back = permute(nums, loc + 1);
for (int i = 0; i < back.size(); i++) {
back[i].push_back(now);
}
int n = back[0].size() - 1;
int size_back = back.size();
for (int i = 0; i < size_back; i++) {
for (int j = 0; j < n; j++) {
vector<int> t = back[i];
swap(t[j], t[n]);
back.push_back(t);
}
}
return back;
}
}
vector<vector<int>> permute(vector<int>& nums) {
return permute(nums, 0);
}
};
法三:全排列放入
将原数组按排列放到一个临时数组中,如果临时数组放满,就把临时数组放到要返回的二维数组中
具体实现:用一个bool数组表示第i个数是否已经放到临时数组中,如果未放入,则将这个数放入,并递归继续放入,然后再把这个数取出
效率:理论上应该是90%多,然而实际只有13.2%,不知道为什么
class Solution {
public:
int nums_size;
vector<vector<int>> res;
vector<int> temp;
vector<bool> is_visit;
void put_in(vector<int>& nums) {
if (temp.size() == nums_size) {
res.push_back(temp);
}
else {
for (int i = 0; i < nums_size; i++) {
if (is_visit[i] == false) {
is_visit[i] = true;
temp.push_back(nums[i]);
put_in(nums);
temp.pop_back();
is_visit[i] = false;
}
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
nums_size = nums.size();
is_visit.resize(nums_size, false);
put_in(nums);
return res;
}
};