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. [
  2. [1,1,2],
  3. [1,2,1],
  4. [2,1,1]
  5. ]

本题有重复元素,条件较难思考,做这个题费了小劲.

总体框架是应用 backtrack 解决.

样例:[1 1 2] -> [1 2 1] -> [2 1 1]

设定一个 vector<bool> used(A.size(), false); 表示哪些元素用过, 用过的用true表示.

[1 1 2] -> [1 2 1] dfs到这种状态后, i 将要为 1, 就是下面的样子.

  1. [1 1 2] 此时所有的 used[0 - 2] 都为 false.
  2. i

if (i > 0 && A[i - 1] == A[i] && !used[i - 1]) continue; // <--这句话,想不出来啊

若无上面那个判断条件(有这个标志的那行 '<--'),将会再次产生下面的序列:

[1 1 2], 这里的第一个1是上面i=1所指的元素,第二个1是i=0的元素.

为防止这种事的发生,就应该跳过i=1的那个元素, 仔细观察, 发现:

  1. i > 0;
  2. A[i] = A[i-1];
  3. A[i-1] = false;

满足上述3条的元素, 就应跳过!

经验:
想写清楚条件,必须把简单例子用笔纸走一遍;
找出自己跑的结果与正确结果不同之处;
针对错误点, 设置if()语句,避免之!

自己代码:

  1. // e.g.
  2. // [1 1 2] -> [1 2 1] -> [2 1 1]
  3. vector<vector<int>> permuteUnique(vector<int>& A) {
  4. sort(A.begin(), A.end());
  5. vector < vector<int> > res;
  6. vector<int> temp;
  7. // 用 used[0-2], true 表用过
  8. vector<bool> used(A.size(), false);
  9. backtrack(res, temp, A, used);
  10. return res;
  11. }
  12. void backtrack(vector<vector<int> >& res, vector<int>& temp, vector<int>& A,
  13. vector<bool> used) {
  14. if (temp.size() == A.size())
  15. res.push_back(temp);
  16. else {
  17. for (int i = 0; i < A.size(); i++) {
  18. if (used[i] == true) {
  19. continue;
  20. }
  21. if (i > 0 && A[i - 1] == A[i] && !used[i - 1])
  22. continue; // <--这句话,想不出来啊
  23. // [1 1 2] -> [1 2 1] dfs到这种状态后, i 将要为 1, 就是下面的样子.
  24. // [1 1 2] 此时所有的 used[0 - 2] 都为 false.
  25. // i
  26. // 若无上面那个判断条件(有这个标志的那行 '<--'),将会再次产生下面的序列:
  27. // [1 1 2], 这里的第一个1是上面i=1所指的元素,第二个1是i=0的元素
  28. // 为防止这种事的发生,就应该跳过i=1的那个元素, 仔细观察, 发现:
  29. // 1. i > 0;
  30. // 2. A[i] = A[i-1];
  31. // 3. A[i-1] = false;
  32. // 满足上述3条的元素,就应跳过!
  33. //
  34. // 经验:
  35. // 想写清楚条件,必须把简单例子用笔纸走一遍;
  36. // 找出自己跑的结果与正确结果不同之处;
  37. // 针对错误点,设置if()语句,避免之!
  38. temp.push_back(A[i]);
  39. used[i] = true;
  40. backtrack(res, temp, A, used);
  41. used[i] = false;
  42. temp.pop_back();
  43. }
  44. }
  45. }

47. Permutations II(medium, backtrack, 重要, 条件较难思考)的更多相关文章

  1. [Leetcode][Python]47: Permutations II

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 47: Permutations IIhttps://oj.leetcode. ...

  2. leetcode46. Permutations 、47. Permutations II、 剑指offer字符串的排列

    字符串排列和PermutationsII差不多 Permutations第一种解法: 这种方法从0开始遍历,通过visited来存储是否被访问到,level代表每次已经存储了多少个数字 class S ...

  3. 【LeetCode】47. Permutations II

    Permutations II Given a collection of numbers that might contain duplicates, return all possible uni ...

  4. leetCode 47.Permutations II (排列组合II) 解题思路和方法

    Permutations II  Given a collection of numbers that might contain duplicates, return all possible un ...

  5. 47. Permutations II (Back-Track, Sort)

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  6. [LeetCode] 47. Permutations II 全排列之二

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  7. (待解决,效率低下)47. Permutations II C++回溯法

    思路是在相似题Permutations的基础上,将结果放到set中,利用set容器不会出现重复元素的特性,得到所需结果 但是利用代码中的/* */部分通过迭代器遍历set将set中的元素放在一个新的v ...

  8. 47. Permutations II (JAVA)

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  9. 【LeetCode】47. Permutations II 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:递归 方法二:回溯法 日期 题目地址:htt ...

随机推荐

  1. spring-oauth-server实践:授权方式四:client_credentials 模式下有效期内重复申请 access_token ?

    spring-oauth-server入门(1-12)授权方式四:client_credentials 模式下有效期内重复申请 access_token ? 一.失效重建邏輯 二.如果沒有失效,不会重 ...

  2. Java8新特性第3章(Stream API)

    Stream作为Java8的新特性之一,他与Java IO包中的InputStream和OutputStream完全不是一个概念.Java8中的Stream是对集合功能的一种增强,主要用于对集合对象进 ...

  3. 南阳OJ-12-喷水装置(二)贪心+区间覆盖

    题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=12 题目大意: 有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有 ...

  4. join()的用法

    Python中有join()和os.path.join()两个函数,具体作用如下:    join():    连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 ...

  5. Menubutton按钮弹出菜单

    #按钮弹出菜单 from tkinter import * root =Tk() def callback(): print('我被调用了') m = Menubutton(root,text = ' ...

  6. openSUSE虚拟机安装并连接Xshell

  7. php array_multisort函数实现按某一字段对二维数组进行排序

    在工作中碰到一个页面如表格似的展示多条数据,要求根据其中的修改时间对数据进行排序, 数据格式类似于 $a = array( 0=>array( editTime=>'' addTime=& ...

  8. Joomla!3.7.0 Core SQL注入漏洞动态调试草稿

    参考joolma的mvc框架讲解:http://www.360doc.com/content/11/1219/18/1372409_173441270.shtml 从这个页面开始下断点:Joomla_ ...

  9. [Luogu 2816]宋荣子搭积木

    Description saruka非常喜欢搭积木,他一共有n块积木.而且saruka的积木很特殊,只能一块块的竖着摞,可以摞很多列.说过saruka的是特殊的积木了,这些积木都非常智能,第i块积木有 ...

  10. 计蒜客NOIP模拟赛4 D2T1 鬼脚图

    鬼脚图,又称画鬼脚,在日本称作阿弥陀签,是一种经典游戏,也是一种简易的决策方法,常常用来抽签或决定分配组合. 下图就是一张鬼脚图,其包含若干条竖线和若干条横线.请注意,横线只能水平连接相邻的两条竖线, ...