zoukankan      html  css  js  c++  java
  • LeetCode: Permutations II 解题报告

    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], and [2,1,1].

    SOLUTION 1:

    还是经典的递归模板。需要处理的情况是:我们先把Num排序,然后只能连续地选,这样就可以避免生成重复的solution.
    例子:1 2 3 4 4 4 5 6 7 8
    444这个的选法只能:4, 44, 444连续这三种选法

    我们用一个visit的数组来记录哪些是选过的。

     1 public class Solution {
     2     public List<List<Integer>> permuteUnique(int[] num) {
     3         List<List<Integer>> ret = new ArrayList<List<Integer>>();
     4         if (num == null || num.length == 0) {
     5             return ret;
     6         }
     7         
     8         // For deal with the duplicate solution, we should sort it.
     9         Arrays.sort(num);
    10         boolean[] visit = new boolean[num.length];
    11         
    12         dfs(num, new ArrayList<Integer>(), ret, visit);
    13         
    14         return ret;
    15     }
    16     
    17     public void dfs(int[] num, ArrayList<Integer> path, List<List<Integer>> ret, boolean[] visit) {
    18         int len = num.length;
    19         if (path.size() == len) {
    20             ret.add(new ArrayList<Integer>(path));
    21             return;
    22         }
    23         
    24         for (int i = 0; i < len; i++) {
    25             // 只能连续地选,这样就可以避免生成重复的solution.
    26             // 例子:1 2 3 4 4 4 5 6 7 8
    27             // 444这个的选法只能:4, 44, 444连续这三种选法
    28             if (visit[i] || (i != 0 && visit[i - 1] && num[i] == num[i - 1])) {
    29                 continue;
    30             }
    31             
    32             // 递归以及回溯
    33             visit[i] = true;
    34             path.add(num[i]);
    35             dfs(num, path, ret, visit);
    36             path.remove(path.size() - 1);
    37             visit[i] = false;
    38         }
    39     }
    40 }
    View Code

    SOLUTION 2:

    用一个pre来记录选过的值,也可以达到同样的目的,只取第一个可以取到的位置,后面再取也是一样的解。用pre记下来,后面就不要再取同样的值了

     1 // SOLUTION 2:
     2     //  使用一个pre来记录。只取第一个可以取的位置
     3     public void dfs(int[] num, ArrayList<Integer> path, List<List<Integer>> ret, boolean[] visit) {
     4         int len = num.length;
     5         if (path.size() == len) {
     6             ret.add(new ArrayList<Integer>(path));
     7             return;
     8         }
     9 
    10         long pre = Long.MIN_VALUE;
    11         for (int i = 0; i < len; i++) {
    12             int n = num[i];
    13             // 只取第一个可取的位置,因为别的位置取到的也没有区别
    14             if (visit[i] || pre == n) {
    15                 continue;
    16             }
    17             pre = n;
    18             
    19             // 递归以及回溯
    20             visit[i] = true;
    21             path.add(n);
    22             dfs(num, path, ret, visit);
    23             path.remove(path.size() - 1);
    24             visit[i] = false;
    25         }
    26     }
    View Code

    GITHUB:

    https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/permutation/PermuteUnique.java

  • 相关阅读:
    GridView只显示日期问题
    自定义一个选择日期的用户控件
    母版页所带来的路径问题
    C#之旅(一): 泛型 和IComparable、IComparer
    使用HttpWebRequest来秒杀
    NameValueCollection Dictionary区别
    在C#中使用代理的方式触发事件 (委托和事件 )(二)(转)
    SQL2005语句实现行转列,列转行
    值类型和引用类型的区别?(转)
    2010年年终总结
  • 原文地址:https://www.cnblogs.com/yuzhangcmu/p/4141085.html
Copyright © 2011-2022 走看看