全排列 II
题目链接
全排列 II
题目描述
注意
- 1 <= nums.length <= 8
- -10 <= nums[i] <= 10
- 数组包含重复数字
- 全排列不可重复
解答思路
- 因为排列组合不能重复,所以先将数组进行排序,如果在某一层已经用过某个相同数字,则跳过后续该数字的排列
- 深度优先遍历找到所有组合,每一层需要从头开始遍历,寻找所有情况,使用visited存储该元素在之前是否使用过,在判断完使用该元素的组合后,需要移除该元素,也就是回溯
代码
class Solution {int n;public List<List<Integer>> permuteUnique(int[] nums) {n = nums.length;List<List<Integer>> res = new ArrayList<>();List<Integer> sonRes = new ArrayList<>();boolean[] visited = new boolean[n];Arrays.sort(nums);dfs(nums, res, sonRes, visited);return res;}public void dfs(int[] nums, List<List<Integer>> res, List<Integer> sonRes, boolean[] visited) {if (sonRes.size() == n) {res.add(new ArrayList<>(sonRes));return;}for (int i = 0; i < n; i++) {if (visited[i]) {continue;}if (i > 0 && !visited[i - 1] && nums[i] == nums[i - 1]) {continue;}sonRes.add(nums[i]);visited[i] = true;dfs(nums, res, sonRes, visited);sonRes.remove(sonRes.size() - 1);visited[i] = false;}}
}
关键点
- 深度优先遍历的思想
- 怎样保证有重复元素的数组中排列组合不重复:如果当前元素在之前已经使用过,则跳过该元素;如果当前元素与上一个元素相等,且上一个元素在该层已经使用过(前几层未使用),则跳过该元素