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; } } }
这道题奇奇怪怪的方法很多,懒得细看了。。。到时候再回顾一下吧。。。。