Leetcode-46. 全排列
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路1:
递归的方法求解,固定前面的数,然后不断交换后面的数。
C++ code:
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
if(nums.size() <= 1){
return {nums};
}
vector<vector<int>> res;
permuteCore(res, nums, 0, nums.size());
return res;
}
void permuteCore(vector<vector<int>> &res, vector<int>& nums, int left, int right){
if(left == right){
res.push_back(nums);
}else{
for(int i = left; i < right; i++){
swap(nums[left], nums[i]);
permuteCore(res, nums, left + 1, right);
swap(nums[left], nums[i]);
}
}
}
};
思路2:
新的思路,算法:
1.首先对数组进行由小到大排序
2.从右边位置开始,找到第一次递增的两个数,然后把第一个数的位置记为i。
3.在i位置右边, 从右边开始,找到第一个大于i位置上数的数,记录其位置为j。
4.交换i位置和j位置上的数。
5.把i位置之后的数逆序。
C++ code:
class Solution {
public:
void next_permute(vector<int> &nums){
int n = nums.size();
int i = n - 2;
while(i >= 0 && nums[i] >= nums[i + 1]){
i--;
}
if(i < 0){
return;
}
int j = n - 1;
while(j > i && nums[j] <= nums[i]){
j--;
}
swap(nums[i], nums[j]);
reverse(nums.begin() + i + 1, nums.end());
}
vector<vector<int>> permute(vector<int>& nums) {
int n = nums.size();
if(n == 0){
return {nums};
}
int res_n = 1;
while(n > 1){
res_n *= n;
n--;
}
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for(int i = 0; i < res_n; i++){
res.push_back(nums);
next_permute(nums);
}
return res;
}
};