[LeetCode] 47. Permutations II

Given a collection of numbers, nums, that might contain duplicates, return all possible unique permutations in any order.

Example 1:

Input: nums = [1,1,2]
Output:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

Example 2:

Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Constraints:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

全排列 II。

一刷的时候直接抄答案,但是依然记不住,二刷终于搞懂了,来写个题解。这个题跟版本一相比只是多了一个条件,就是 input 数组里面是有重复元素的,但是得出的 permutation 里面不能有重复。

思路依然是 backtracking,同时因为需要去掉重复元素带来的困扰,我们需要用一个 visited 数组来记录数字是否被用过。这里我参考了LC中文网一个大神的解释,讲的非常好,尤其帮助我理解了回溯的具体过程和怎么去重的部分。回溯的 helper 函数的主要部分还是跟其他回溯类型的题差不多,但是这个题需要先对 input 排序(帮助剪枝)和额外的 visited 数组记录。

时间O(N * N!)

空间O(N * N!)

Java实现

18行判断是否跳过当前数字,是如下两个原则

  • 如果当前数字已经 visited 过了,自然就跳过
  • 如果当前数字跟之前一个数字相同且之前一个数字是没有被 visited 过的(实际是回溯的时候又被标记成 false 的),跳过当前这个数字
    • 举例,比如 [1a, 1b, 2a],你要确保 1a 一定要在 1b 之前,否则就会有重复的解。避免这个问题的办法(可以看一下loickenleetcode的评论)就是当你发现 1b == 1a 同时 1a 还没有被 visited 过的时候,你就必须要跳过 1b
 1 class Solution {
 2     public List<List<Integer>> permuteUnique(int[] nums) {
 3         List<List<Integer>> res = new ArrayList<>();
 4         if (nums == null || nums.length == 0) {
 5             return res;
 6         }
 7         Arrays.sort(nums);
 8         helper(res, new ArrayList<>(), nums, new boolean[nums.length]);
 9         return res;
10     }
11 
12     private void helper(List<List<Integer>> res, List<Integer> list, int[] nums, boolean[] visited) {
13         if (list.size() == nums.length) {
14             res.add(new ArrayList<>(list));
15             return;
16         }
17         for (int i = 0; i < nums.length; i++) {
18             if (visited[i] || i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
19                 continue;
20             }
21             visited[i] = true;
22             list.add(nums[i]);
23             helper(res, list, nums, visited);
24             visited[i] = false;
25             list.remove(list.size() - 1);
26         }
27     }
28 }

 

LeetCode 题目总结

posted @ 2020-05-31 15:54  CNoodle  阅读(472)  评论(0编辑  收藏  举报