leetcode 46 全排列(Medium)
题目来源:leetcode 46 全排列
题目描述:
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
解题思路:
回溯,先固定第一个数(第一个数和所有数交换,取的所有结果),然后递归求的后面数的全排列,再撤销交换。结束的出口是,只剩一个字符。
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> ans;
permute(nums,ans,0);
return ans;
}
void permute(vector<int>nums,vector<vector<int>> &ans,int start)
{
//所有数都填完了,加入结果中
if(start==nums.size()-1)
{
if(find(ans.begin(),ans.end(),nums)==ans.end()) ans.push_back(nums);
return;
}
else
{
for(int i=0;i<nums.size();i++)
{
//不断交换,动态固定第一个数
swap(nums[start],nums[i]);
//递归取得后面数的全排列
permute(nums,ans,start+1);
//撤销操作
swap(nums[start],nums[i]);
}
}
}
};
另一种写法:
class Solution {
public:
vector<vector<int>> ans;
vector<vector<int>> permute(vector<int>& nums) {
vector<int> track;
backtrack(nums,track);
return ans;
}
void backtrack(vector<int> &nums,vector<int> &track){
//结束条件
if(track.size()==nums.size()){
ans.push_back(track);
return;
}
for(int i=0;i<nums.size();i++){
//排除不合法的选择
if(find(track.begin(),track.end(),nums[i])!=track.end()) continue;
//做选择
track.push_back(nums[i]);
//下一层决策
backtrack(nums,track);
//撤销选择
track.pop_back();
}
}
};