Permutations II Leetcode

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]
]
 
这道题的不同之处就在于有重复的了,那前面的哪两种方法都不可以直接用。直观的笨办法就是,加之前判断一下是不是已经有了。
public class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        if (nums == null || nums.length == 0) {
            return result;
        }
        List<Integer> current = new ArrayList<>();
        Arrays.sort(nums);
        current.add(nums[0]);
        result.add(current);
        int size = 0;
        for (int i = 1; i < nums.length; i++) {
            List<List<Integer>> newResult = new ArrayList<>();
            for (List<Integer> l : result) {
                for (int j = 0; j <= l.size(); j++) {
                    List<Integer> tmp = new ArrayList<>(l);
                    tmp.add(j, nums[i]);
                    if (!newResult.contains(tmp)) {
                        newResult.add(tmp);
                    }
                }
            }
            result = newResult;
        }
        return result;
    }
}

加一个hashset,也快不到哪里去。。。

public class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        if (nums == null || nums.length == 0) {
            return result;
        }
        List<Integer> current = new ArrayList<>();
        Arrays.sort(nums);
        current.add(nums[0]);
        result.add(current);
        int size = 0;
        for (int i = 1; i < nums.length; i++) {
            Set<List<Integer>> hs = new HashSet<>();
            List<List<Integer>> newResult = new ArrayList<>();
            for (List<Integer> l : result) {
                for (int j = 0; j <= l.size(); j++) {
                    List<Integer> tmp = new ArrayList<>(l);
                    tmp.add(j, nums[i]);
                    if (hs.add(tmp)) {
                        newResult.add(tmp);
                    }
                }
            }
            result = newResult;
        }
        return result;
    }
}

用dfs反倒是快了很多,用一个数组来表示有没有用过。此时,如果循环回来遍历,如果前一个数没有用过,后一个数等于前一个数,那么前一个数开头的所有可能都已经囊括了,就不用再考虑了。

public class Solution {
    List<List<Integer>> result;
    List<Integer> current;
    boolean[] used;
    public List<List<Integer>> permuteUnique(int[] num) {
       result = new ArrayList<>();
       if (num == null || num.length == 0) {
           return result;
       }
       Arrays.sort(num);
       current = new ArrayList<>();
       used = new boolean[num.length];
       helper(num, 0);
       return result;
    }
    public void helper(int[] num, int control) {
        if (control >= num.length) {
            result.add(new ArrayList<>(current));
        }
        for (int i = 0; i < num.length; i++) {
            if (i > 0 && num[i] == num[i - 1] && !used[i - 1] || used[i]) {
                continue;
            }
            current.add(num[i]);
            used[i] = true;
            helper(num, control + 1);
            current.remove(current.size() - 1);
            used[i] = false;
        }
    }
}

这道题奇奇怪怪的方法很多,懒得细看了。。。到时候再回顾一下吧。。。。

posted @ 2017-03-22 05:05  璨璨要好好学习  阅读(152)  评论(0编辑  收藏  举报