(一) 题目描述
给定一个可包含重复数字的序列,返回所有不重复的全排列
示例:
输入:[1,1,2]
输出:
[
[1,1,2]
[1,2,1]
[2,1,1]
]
(二)解题算法
- 先对给定的序列nums进行排序,使得大小相同的元素排在一起.
- 新建一个used数组,大小与nums相同,用来标记在本次DFS读取中位置 i 的元素是否已经添加到list中了.
- 根据思路可知,我们选择跳过一个数,当且仅当这个数与前一个数相等,并且前一个数未被添加到list中.
(三)LeetCode AC代码
public class Solution { List<List<Integer>> res = new ArrayList<List<Integer>>(); public List<List<Integer>> permuteUnique(int[] nums) { int len = nums.length; if(len==0||nums==null) return res; boolean[] used = new boolean[len]; List<Integer> list = new ArrayList<Integer>(); Arrays.sort(nums); dfs(nums, used, list, len); return res; } public void dfs(int[] nums, boolean[] used, List<Integer> list, int len) { if(list.size()==len) { res.add(new ArrayList<Integer>(list)); return ; } for (int i=0; i<len; i++) { // 当前位置的数已经在List中了 if(used[i]) continue; // 当前元素与其前一个元素值相同 且 前元素未被加到list中,跳过该元素 if(i>0 && nums[i]==nums[i-1] && !used[i-1]) continue; // 深度优先搜索遍历 used[i]=true; list.add(nums[i]); dfs(nums, used, list, len); list.remove(list.size()-1); used[i]=false; } } }
迷茫的尽头,就是光明