Leetcode 47.全排列II
题目要求
- 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
示例 1:
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
示例 2:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
回溯法
与Leetcode46类似,区别在于这道题不仅需要树枝去重,还需要树层去重
需要注意的是代码
1 2 3
| if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) { continue; }
|
如果改成used[i - 1] == true也是正确的
这是因为used[i - 1] == true是在树枝上去重,used[i - 1] == false是在树层上去重,树层去重效率更高
![used[i-1]==false树层去重](/image/Java/%E7%AE%97%E6%B3%95Leetcode/Day37_Leetcode47.%E5%85%A8%E6%8E%92%E5%88%97II/%E5%8E%BB%E9%87%8D1.png)
![used[i-1]==true树枝去重](/image/Java/%E7%AE%97%E6%B3%95Leetcode/Day37_Leetcode47.%E5%85%A8%E6%8E%92%E5%88%97II/%E5%8E%BB%E9%87%8D2.png)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class Solution { public List<List<Integer>> res = new ArrayList<>(); public List<Integer> path = new ArrayList<>(); public List<List<Integer>> permuteUnique(int[] nums) { boolean[] used = new boolean[nums.length]; Arrays.fill(used, false); Arrays.sort(nums); backtrack(nums, used); return res; }
public void backtrack(int[] nums, boolean[] used) { if (path.size() == nums.length) { res.add(new ArrayList<>(path)); return; } for (int i = 0; i < nums.length; i++) { if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) { continue; } if (used[i] == true) continue; used[i] = true; path.add(nums[i]); backTrack(nums, used); path.remove(path.size() - 1); used[i] = false; } } }
|