zoukankan      html  css  js  c++  java
  • 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过程已经进行到下面:


     




  • 相关阅读:
    php模式设计之 工厂模式
    SDK以及部署的SDK的思路
    手机用fiddler抓包开发测试
    搭建GIT服务端
    TP5.0以上数据库增加数据异常
    lnmp一键安装后的配置改动建议
    TPshop5最新版 安装 nginx 开启PATHINFO 模式资源加载路径加载失败问题,适用tp3.2PATHINFO模式REWRITE模式
    jquery写拉动条
    JS(JQ)分页 个人查看,没注释
    ecshop 分页
  • 原文地址:https://www.cnblogs.com/zhxshseu/p/a5b6798ef83004e6acb7d0932fee7950.html
Copyright © 2011-2022 走看看