Permutations
Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3]
have the following permutations:
[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
nums的每个数都与其后面的数交换,采用深度递归
class Solution {
//递归,每次调用时都将当前的数与后面的数交换
void DFS(vector
& nums, int start, vector
> & r)
{
if(start>=nums.size()) r.push_back(nums);
else
{
for(int i=start;i
> permute(vector
& nums) { int n=nums.size(); vector
> r; DFS(nums,0,r); return r; } };
void DFS(vector<int> & nums, int start, vector<vector<int>> & r)//注意这里是nums的引用传递
Permutations II
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]
have the following unique permutations:
[ [1,1,2], [1,2,1], [2,1,1] ]
https://discuss.leetcode.com/topic/8831/a-simple-c-solution-in-only-20-lines/47
先将数组排好序,然后进行元素交换,这里排重是个问题。如果采用递归时,将nums进行引用传递,第i个递归内的第i+1个递归会改变nums的值,
swap(nums, start, i);
permutating(ans, Arrays.copyOf(nums, nums.length), start+1);
swap(nums, start, i);
这样只是交换回来,是无法恢复原样的,也会有重复。
通过的代码:
void DFS(vector<vector<int>>& r,vector<int> nums,int start)//这里的nums是值传递。对于数组中的每个数如果前面没有与它重复的数,
那么它一定可以交换到当前迭代的首部,它后面的如果与他重复,就会被忽略,这样保证第i次迭代的首个元素不会有重复,然后再进行下一次迭代。
class Solution {
//nums是值传递
void DFS(vector
>& r,vector
nums,int start)
{
if(start==nums.size()-1)
{
r.push_back(nums);
return ;
}else
{
for(int i=start;i
> permuteUnique(vector
& nums) { sort(nums.begin(),nums.end()); vector
> r; DFS(r,nums,0); return r; } };
(1,2,2,3) (pos = 0, i = 0)
(2,1,2,3) (pos = 0, i = 1)
(2,1,2,3) (pos = 0, i =2) skipped, since array[0]=array[2]; //排重
(3,1,2,2) (pos = 0, i =3)
但按照引用传递的递归, 它的后面3个元素不是排好序的
(1,2,2,3) (pos = 0, i = 0)
(2,1,2,3) (pos = 0, i = 1)//1序列
(2,2,1,3) (pos = 0, i =2) //这回产生重复,下一次递归从pos=1开始,其子序列与上一个1序列产生的子序列一样
(3,2,2,1) (pos = 0, i =3)
如果排重的过滤条件为:if (nums[i] == nums[i - 1] && i != begin)也不行,排好序的队列,会在子递归的过程中失序,下次递归就无法排重了。另一种解法:增加一个数组used,用来表示第i个数是否在该次迭代中用过,每次选一个元素加入到存储排列的vector<int>中;
这里排重通过nums[i]和nums[j]是否相等及used来确定。
class Solution {
void DFS(vector
>& r,vector
& nums,vector
& nu, vector
&used) { if(nu.size()==nums.size()) { r.push_back(nu); return ; }else { for(int i=0;i
0&&nums[i]==nums[i-1] && used[i-1]) //这里用了used[i-1],可以理解为前面nums[i-1]已经用了,这个和它一样的 //nums[i]就可以直接跳过了,但是原版的是!used[i-1],两个都能通过,实在不能理解呢 continue; used[i]=true; nu.push_back(nums[i]); DFS(r,nums,nu,used); used[i]=false; nu.pop_back(); } } } public: vector
> permuteUnique(vector
& nums) { sort(nums.begin(),nums.end()); vector
> r; vector
used(nums.size(),false); vector
nu; DFS(r,nums,nu,used); return r; } };