题目:
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
输入:nums = [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) {
dfs(nums);//调用递归
return res;
}
private:
vector<vector<int>> res;//定义二维数组保存最终结果
vector<int> temp;//定义临时数组 保存当前的排列组合
void dfs(vector<int>& nums)
{
//当temp的元素个数等于nums的,说明当前这个组合已经排列完了,
if(temp.size()==nums.size())
{
res.push_back(temp);//将temp保存到res中
return;
}
for(int i=0;i<nums.size();i++)
{
//将用过的元素置为99,以此来判断当前的nums[i]是否被使用过
//不等于99,说明没有被使用过
if(nums[i]!=99)
{
//用num将nums[i]暂存起来
int num=nums[i];
//将元素存放到temp中
temp.push_back(nums[i]);
//nums[i]使用过了,就将值改为99
nums[i]=99;
//继续递归
dfs(nums);
//return后,回溯到这里
//将nums[i]的值改回来
nums[i]=num;
//并从temp删除
temp.pop_back();
}
}
}
};
题目升级:
给定一个可包含重复数字的序列 nums
,按任意顺序 返回所有不重复的全排列。
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
与上一题的区别在于包含重复元素,所以我们需要对原数组进行排序,保证相同元素是相邻的,再通过添加判断条件,对重复值进行去重
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
//对数组排序,保证相同的元素相邻,以便后面去重
sort(nums.begin(),nums.end());
dfs(nums);
return res;
}
private:
vector<vector<int>> res;
vector<int> temp;
void dfs(vector<int>& nums)
{
if(temp.size()==nums.size())
{
res.push_back(temp);
return;
}
for(int i=0;i<nums.size();i++)
{
//不同之处在于,遇到重复值需要跳过
//举个例子,对于两个相同的数1,1,我们将其命名为a和b, a表示第一个1,b表示第二个1; 那么,不做去重的话,会有两种重复排列 ab, ba, 我们只需要取其中任意一种排列;那么我们只需要控制他们的访问顺序,a必须在b之前
//只有当nums[i - 1]被使用过了,我们才使用nums[i]
//此时nums[i - 1]没有被使用,所以直接跳过这一轮循环
if (i > 0 && nums[i] == nums[i - 1] && nums[i - 1]!=99)
{
continue;
}
if(nums[i]!=99)
{
int num=nums[i];
temp.push_back(nums[i]);
nums[i]=99;
dfs(nums);
nums[i]=num;
temp.pop_back();
}
}
}
};