网址
题目
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Example:
Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
解法
嘻嘻 最简单的方法就是跟之前一样的做,但是如果res
中该存在该组合则加进去,如果不存在就不加
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if(nums == null || nums.length == 0) return res;
recursiveSwap(nums, 0, res);
return res;
}
private void recursiveSwap(int[] nums, int pos, List<List<Integer>> res){
if(pos > nums.length-1){
List<Integer> temp = new ArrayList<>();
for(int i=0; i<nums.length;i++){
temp.add(nums[i]);
}
if(!res.contains(temp)) res.add(temp);
return;
}
for(int i=pos; i<nums.length;i++){
int tmp = nums[pos];
nums[pos] = nums[i];
nums[i] = tmp;
recursiveSwap(nums, pos+1, res);
tmp = nums[pos];
nums[pos] = nums[i];
nums[i] = tmp;
}
}
}
发现之前写的代码都有点小问题,还是排列的顺序上,因为每次都只是交换两个数字,假设原数组按顺序排列,如果交换的是非相邻项,那整体不一定是从小到大的顺序。但是leetcode貌似并未考核顺序的排列,所以能够通过实例。
还是参考该作者的博文 https://www.jianshu.com/p/a08d7fd65572 该问题无非是树的剪枝,那么该如何剪枝呢?
刚开始考虑先排序,每次交换检查当前值与前一个值的大小,如果相等就跳过;但是考虑这样的情景:我们现在在遍历3个子树中最左边的一个,此时我们要交换1和2,1和前一个值一样就被跳过去了;所以我们需要有一个数组来记录当前遍历的是哪棵树,有没有遍历完全。
public class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
if (nums == null || nums.length == 0) {
return result;
}
boolean[] visited = new boolean[nums.length];
List<Integer> temp = new ArrayList<>();
Arrays.sort(nums);
permuteRecursively(nums, visited, temp, result);
return result;
}
private void permuteRecursively(int[] nums, boolean[] visited,
List<Integer> temp, List<List<Integer>> result) {
if (temp.size() >= nums.length) {
result.add(new ArrayList<>(temp));
return;
}
for (int i = 0; i < nums.length; i++) {
// 前一层递归已经访问过,跳过
if (visited[i]) {
continue;
}
// i和前面的相同,但是前面的没有访问,
// 只能是因为前面的已经退出来了,那这个也就跳过
if (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
continue;
}
visited[i] = true;
temp.add(nums[i]);
permuteRecursively(nums, visited, temp, result);
temp.remove(temp.size() - 1);
visited[i] = false;
}
}
}
自己尝试在上一次的基础上加老是出问题,由于leetcode访问不稳定,总是提交不了 耗了太长时间也就作罢。。。