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]]
给一个数组,输出数组元素的所有的unique排列。
数组中有重复的数字,但排列不能重复。
思路:
DFS
因为有重复的数字,为了跨过重复的数字,要让重复的数字放在一起,所以要排序。
因为是排列,会出现不同的顺序;所以DFS内可以访问当前元素之前的元素,DFS内访问下标要从0开始。
另外跳过重复元素时,不能一见到和前面元素一样就跳过,
比如[1, 1, 2]
如果看见第2个1和第1个1一样就直接跳过,那样元素就不够了。
怎么判断呢,
在看见和前面元素一样的时候,要判断前面的是不是正在访问,如果正在访问说明还需要添加元素,不然不够了,不需要跳过。
如果前面元素没有在访问,说明要以现在元素为首DFS了,会出现和前面排列一样的情况,这时要跳过。
class Solution {
List<List<Integer>> res = new ArrayList<>();
int n = 0;
boolean[] visited;
public List<List<Integer>> permuteUnique(int[] nums) {
n = nums.length;
visited = new boolean[n];
Stack<Integer> st = new Stack<>();
Arrays.sort(nums);
dfs(nums, st);
return res;
}
void dfs(int[] nums, Stack<Integer> st) {
if(st.size() == n) {
res.add(new ArrayList<Integer>(st));
return;
}
for(int i = 0; i < n; i ++) {
if(visited[i]) continue;
if(i > 0 && nums[i] == nums[i-1] && !visited[i-1]) continue;
st.push(nums[i]);
visited[i] = true;
dfs(nums, st);
st.pop();
visited[i] = false;
}
}
}