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

next_permutation()

直接使用std::next_permutation(),代码与上一题相同。

重新实现next_permutation()

重新实现std::next_permutation(),代码与上一题相同。

递归

递归函数permute()的参数p,是中间结果,它的长度又能标记当前走到了哪一步,用于判断收敛条件。

扩展节点,每次从小到大,选一个没有被用光的元素,直到所有元素被用光。

本题不需要判重,因为状态装换图是一颗有层次的树。

  1. // Permutations II
  2. // 深搜,时间复杂度O(n!),空间复杂度O(n)
  3. public class Solution {
  4. public List<List<Integer>> permuteUnique(int[] nums) {
  5. Arrays.sort(nums); // 必须排序
  6. List<List<Integer>> result = new ArrayList<>(); // 最终结果
  7. List<Integer> path = new ArrayList<>(); // 中间结果
  8. // 记录每个元素的出现次数
  9. HashMap<Integer, Integer> counterMap = new HashMap<>();
  10. for (int i : nums) {
  11. counterMap.put(i, counterMap.getOrDefault(i, 0) + 1);
  12. }
  13. // 将HashMap里的pair拷贝到一个数组里
  14. Pair[] counters = new Pair[counterMap.size()];
  15. int i = 0;
  16. for (Map.Entry<Integer, Integer> entry : counterMap.entrySet()) {
  17. counters[i++] = new Pair(entry.getKey(), entry.getValue());
  18. }
  19. Arrays.sort(counters);
  20. // 每个元素选择了多少个
  21. HashMap<Integer, Integer> selected = new HashMap<>();
  22. for (Pair p : counters) {
  23. selected.put(p.key, 0 );
  24. }
  25. n = nums.length;
  26. permute(counters, selected, path, result);
  27. return result;
  28. }
  29. private int n;
  30. void permute(Pair[] counters, HashMap<Integer,Integer> selected,
  31. List<Integer> path, List<List<Integer>> result) {
  32. if (n == path.size()) { // 收敛条件
  33. result.add(new ArrayList<>(path));
  34. }
  35. // 扩展状态
  36. for (Pair counter : counters) {
  37. if (selected.get(counter.key) < counter.value) {
  38. path.add(counter.key);
  39. selected.put(counter.key, selected.get(counter.key) + 1);
  40. permute(counters, selected, path, result);
  41. path.remove(path.size() - 1);
  42. selected.put(counter.key, selected.get(counter.key) - 1);
  43. }
  44. }
  45. }
  46. static class Pair implements Comparable<Pair> {
  47. int key;
  48. int value;
  49. public Pair(int key, int value) {
  50. this.key = key;
  51. this.value = value;
  52. }
  53. @Override
  54. public int compareTo(Pair o) {
  55. if (this.key < o.key) return -1;
  56. else if (this.key > o.key) return 1;
  57. else {
  58. return this.value - o.value;
  59. }
  60. }
  61. }
  62. }

相关题目

原文: https://soulmachine.gitbooks.io/algorithm-essentials/content/java/brute-force/permutations-ii.html