题目要求

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

对于其基础题PermutationsI请参考我的另一篇博客
这里添加的难度在于,排列组合的数字中可能存在重复。这就需要想方法,将结果集中重复的结果删去。而这里,我参考了另一名答题者的答案,在试图将数字添入结果集中时,就判断会不会产生重复的结果,从而使避免重复。

PermutationsI也可以使用此方法。。

代码和解析

这里采用了递归的思路。避免重复的核心思路在于,使用一个boolean数组来代表当前的数值是否已经被使用过。当前的值如果已经被使用过,则继续判断下一个数值。如果当前的值为重复值,则只要前面的值没有被使用过,则当前值就不可以被使用。这样确保了只有第一个出现的重复值可以算进结果集,后序重复的情况不会被添加进结果集。
例如,假设输入的数组为[1,1,2]。则当第一个1被添加进结果集时,可以继续使用第二个1作为元素添加进结果集从而生成112。同理,当试图将第二个1作为第一个元素添加进结果集时,只要第一个1还没有被使用过,则不可以使用第二个1。因此,112不会被重复的添加进结果集。
其实,这个算法保证了所有重复的数字在结果集中的顺序和在原输入数组中的顺序是相同的。假设将[1,1,2]表示为[1,1#,2],那么结果集中会确保1永远在数值1#的前面,从而避免了11#2和1#12的重复情况出现。

代码如下:

class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
if(nums==null||nums.length==0) return res;
//该数组用来标记每个位置的元素是否使用以保证每个位置的元素只能使用一次。控制递归遍历(往list后面添加元素)中该元素是否已经使用。
boolean[] used=new boolean[nums.length];
Arrays.sort(nums);
List<Integer> list=new ArrayList<>();
helper(nums,res,list,used);
return res;
} public void helper(int[] nums,List<List<Integer>> res,List<Integer> list,boolean[] used){
if(nums.length==list.size()){
res.add(new ArrayList<Integer>(list));
return ;
}
for(int i=0;i<nums.length;i++){
if(used[i]) continue; //该元素使用过了。
//下一个重复值只有在前一个重复值被使用的情况下才可以使用。
/*
    这个!used[i-1]条件是为深度遍历准备的。
对于当前层遍历时,每遍历一个元素结束后就会设为false然后遍历下一个,所以可以跳过重复元素,避免相同元素出现在同一个位置。
对于深度遍历(递归,往结果集中继续添加元素),需要使用!used[i-1]来保证后面的相同元素可以往后面的结果集中添加。
      比如[1,1,2].第一层遍历第一个1时,设为true后,递归往后面添加第二个元素,此时也是从第一个元素开始遍历,
      因为此时used[0]为true,所以跳过,i=1,此时如果没有!used[i-1],也会跳过第二个1了,所以需要加上这个条件。
      
      */ if(i>0&&nums[i]==nums[i-1]&&!used[i-1]) continue;
used[i]=true;
list.add(nums[i]);
helper(nums,res,list,used);
//下面这两步,为了同层遍历,同层遍历是给一个位置轮流添加元素。所以需要将上一个添加的元素删了,然后删除标记,遍历下一个元素
used[i]=false;
list.remove(list.size()-1);
}
}
}

参考:https://segmentfault.com/a/1190000009513703

permutations II(全排列 2)的更多相关文章

  1. [LeetCode] Permutations II 全排列之二

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

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

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

  3. [Leetcode] permutations ii 全排列

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

  4. [LeetCode] 47. Permutations II 全排列 II

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

  5. 47. Permutations II (全排列有重复的元素)

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

  6. Leetcode47. Permutations II全排列2

    给定一个可包含重复数字的序列,返回所有不重复的全排列. 示例: 输入: [1,1,2] 输出: [ [1,1,2], [1,2,1], [2,1,1] ] 在全排列1题目的基础上先排序,目的是把相同的 ...

  7. leetcode Permutations II 无重全排列

    作者:jostree  转载请注明出处 http://www.cnblogs.com/jostree/p/4051169.html 题目链接:leetcode Permutations II 无重全排 ...

  8. Leetcode之回溯法专题-47. 全排列 II(Permutations II)

    Leetcode之回溯法专题-47. 全排列 II(Permutations II) 给定一个可包含重复数字的序列,返回所有不重复的全排列. 示例: 输入: [1,1,2] 输出: [ [1,1,2] ...

  9. LeetCode:Permutations, Permutations II(求全排列)

    Permutations Given a collection of numbers, return all possible permutations. For example, [1,2,3] h ...

随机推荐

  1. 为你的MacOS App添加开机自启动(Swift)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/52104828 ...

  2. Devstack: A copy of worked local.conf I'm sharing with you.

    service_plugins = neutron.services.firewall.fwaas_plugin.FirewallPlugin [service_providers] service_ ...

  3. Java子类实例化的过程

    //继承 class Work{ public Work(){ System.out.println("父类中的方法"); } } class Worker extends Wor ...

  4. 关于js校验,检验常见的比如:电话,数字,邮箱,手机号等等

     /**  验证数字:^[0-9]*$  验证n位的数字:^\d{n}$  验证至少n位数字:^\d{n,}$  验证m-n位的数字:^\d{m,n}$  验证零和非零开头的数字:^(0|[1-9 ...

  5. 【一天一道LeetCode】#88. Merge Sorted Array

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given t ...

  6. 读书笔记 - reword (重来)

    reword (重来) 虽然我是一个不是很喜欢看书的人,但是公认的是看书对提高个人的水平是很有帮助的. 而且我想,如果我要写一本书,我一定会经过多次校验.经过长时间思考确保无误后才会出版的.所以我想看 ...

  7. 11、Libgdx的音频

    (官网:www.libgdx.cn) Libgdx提供了简单的方法对较小的音效和磁盘中的音乐进行回放.它同样也提供了方便的针对音频硬件的读写权限. 所有的音频操作都通过audio模块来完成: Audi ...

  8. PO标准form的一点疑问

    最近在修改采购订单form的时候,发现采购订单form往数据库中插数据的地方找不到,程序太多.我们又需要根据界面上的item的值在订单界面数据生成数据库数据时插值时,只能是想其他办法,一种是在on-i ...

  9. linux shell编程语句if、case.

    shell学习笔记--if,case shell的控制流结构主要有if语句.for语句.case语句.while语句.until语句这五种,在shell中这些语句的用法有点类似C语言,很容易学会,但也 ...

  10. 9、Libgdx的输入处理

    (官网:www.libgdx.cn) 不同的平台有着不同的输入方式.桌面用户可以通过键盘和鼠标与应用进行交互,基于浏览器的游戏也是这样.在Android中,鼠标被触摸屏所替代,通常没有实体键盘.And ...