47. 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]
]

分析

因为可能出现重复的元素
1. 对数组进行排序,ascending的顺序
2. 对begin位置的元素交换的时候,保证交换的一定是不同的元素即可

使用 引用nums并且回溯之前再次swap的方法不能AC,很奇怪?不能AC的代码如下:
测试[1,1,2,2]数据,代码是ok的,但是测试[0,0,1,1,2,2]代码,虽然值相同,但是下面的代码并不是都能按照从小到大的顺序生成全排列。
下面的代码答案最后几个是:[..[2,2,1,0,0,1],[2,2,0,1,1,0],[2,2,0,1,0,1],[2,2,0,0,1,1]]
但是标准答案是:       [..[2,2,0,1,1,0],[2,2,1,0,0,1],[2,2,1,0,1,0],[2,2,1,1,0,0]]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>> results;
        sort(nums.begin(), nums.end());
        helper(results, 0, nums);
        return results;
    }
     
    void helper(vector<vector<int>> & results,int begin, vector<int> & nums){
        if(begin == nums.size() - 1 ){
            results.push_back(nums);
            return;
        }
         
        for(int i = begin; i < nums.size(); ++i){
            if(i!= begin && (nums[begin] == nums[i] || nums[i] == nums[i - 1])) continue;
            swap(nums[begin], nums[i]);
            helper(results, begin + 1, nums);
            swap(nums[begin], nums[i]);
        }
    }
};

而使用传值的方式去DFS,则可以AC,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>> results;
        sort(nums.begin(), nums.end());
        helper(results, 0, nums);
        return results;
    }
     
    void helper(vector<vector<int>> & results,int begin, vector<int> nums){
        if(begin == nums.size() - 1 ){
            results.push_back(nums);
            return;
        }
         
        for(int i = begin; i < nums.size(); ++i){
            if(i!= begin && nums[begin] == nums[i]) continue;
            swap(nums[begin], nums[i]);
            helper(results, begin + 1, nums);
             
        }
    }
};

后来一步步分析,关键还就在于 这里的代码,swap之后,DFS之后,并没有再次进行swap还原。
例如:
假设DFS过程已经进行到下面:


 




原文地址:https://www.cnblogs.com/zhxshseu/p/a5b6798ef83004e6acb7d0932fee7950.html