zoukankan      html  css  js  c++  java
  • [LintCode] Permutations II

    Given a list of numbers with duplicate number in it. Find all unique permutations.

    Example

    For numbers [1,2,2] the unique permutations are:

    [
      [1,2,2],
      [2,1,2],
      [2,2,1]
    ]
    
    Challenge 

    Using recursion to do it is acceptable. If you can do it without recursion, that would be great!

    This problem is a follow up of Permutation with an extra condition: there are duplicated numbers in the given list. 

    In order to avoid duplicated permuations, we use a "representative selection" principle.

    Take [1, 2, 2, 2, 3] as an example,  when the current permutation needs a 2 and there are more than one 2 left in the 

    unused numbers pool, if we use the same algorithm with Permuation(no duplicated numbers), we would have duplicated answers.

    This is shown as follows.

    Say, we've already picked 1 and 2 for the current permutation. {2, 2, 3} are left for further picks. If we need to pick another 2, we can either 

    pick the first or second 2 in {2, 2, 3}, both leaving {2, 3} for further picks. These two picks generate duplicated permutations. To avoid this,

    we rule that we only pick the first unpicked 2 and skip the case where we pick the second 2 out of {2, 2, 3}. 

    To achieve this "representative selection" principle, we need to sort the input array first so that all duplicated numbers are adjacent. This way,

    when picking duplicated numbers, we can check if its previous duplicated neighbor has been picked or not. If it has, we know this is not a duplicate 

    case; If it hasn't, then we know for the same permutations, we could've picked its previous unpicked neighbor as their representative, skip this case.

     1 public class Solution {
     2     public List<List<Integer>> permuteUnique(int[] nums) {
     3         List<List<Integer>> results = new ArrayList<>();
     4         if(nums == null || nums.length == 0) {
     5             results.add(new ArrayList<Integer>());
     6             return results;
     7         }
     8         boolean[] used = new boolean[nums.length];
     9         for(int i = 0; i < used.length; i++) {
    10             used[i] = false;
    11         }
    12         Arrays.sort(nums);
    13         permuteUniqueDfs(results, new ArrayList<Integer>(), nums, used);
    14         return results;
    15     }
    16     private void permuteUniqueDfs(List<List<Integer>> results, List<Integer> list,
    17                                     int[] nums, boolean[] used) {
    18         if(list.size() == nums.length) {
    19             results.add(new ArrayList<Integer>(list));
    20             return;
    21         }
    22         for(int i = 0; i < nums.length; i++) {
    23             if(used[i] || (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false)) {
    24                 continue;
    25             }
    26             list.add(nums[i]);
    27             used[i] = true;
    28             permuteUniqueDfs(results, list, nums, used);
    29             list.remove(list.size() - 1);
    30             used[i] = false;
    31         }
    32     }
    33 }

    Related Problems

    Next Permutation II

    Permutation Sequence

    Next Permutation

    Permutations

  • 相关阅读:
    文件操作工具类
    批量插入数据到 MySQL的几种方式
    C#队列学习笔记:RabbitMQ使用多线程提高消费吞吐率
    C#队列学习笔记:RabbitMQ延迟队列
    C#队列学习笔记:RabbitMQ优先级队列
    C#队列学习笔记:RabbitMQ实现客户端相互通讯
    C#队列学习笔记:RabbitMQ搭建集群
    C#队列学习笔记:RabbitMQ安装及使用
    C#队列学习笔记:RabbitMQ基础知识
    C#队列学习笔记:MSMQ入门二
  • 原文地址:https://www.cnblogs.com/lz87/p/7494138.html
Copyright © 2011-2022 走看看