全排列
给定一个没有重复数字的数组,返回其
所有
可能的排列
递归树
- 以
[1,2,3]
为例
- 每一次递归都需要遍历整个数组
- 如何避免重复添加元素呢?
- 设置一个
访问标志数组
代码
public static List<List<Integer>> permute(int[] nums) {
// write your code here
List<List<Integer>> results = new ArrayList<>();
List<Integer> permute = new ArrayList<>();
if (nums.length == 0){
results.add(permute);
return results;
}
boolean[] visited = new boolean[nums.length];
//初始化为false
for (int i=0; i<visited.length; i++){
visited[i] = false;
}
permuteHelper(nums, visited, permute, results);
return results;
}
/**
* 20190813
* @param nums 原始数组
* @param visited 访问标志位
* @param permute 一个全排列
* @param results 结果集
*/
private static void permuteHelper(int[] nums,
boolean[] visited,
List<Integer> permute,
List<List<Integer>> results){
//递归出口
if (permute.size() == nums.length){
results.add( new ArrayList<>(permute));
return;
}
for (int i=0; i<nums.length; i++){
//如果某个元素 已经被访问过了 则访问下一个
if (visited[i]){
continue;
}
permute.add(nums[i]);
visited[i] = true;
permuteHelper(nums, visited, permute, results);
permute.remove(permute.size() - 1);
visited[i] = false;
}
}
带重复元素的全排列
给定一包含重复元素的数组,求其
所有
可能的排列
- 以
[1,1,2]
为例,如果按上一题的解法,可以画出如下的递归树:
- 这里去重的思路和
带重复元素的子集非常类似
- 可以简单小结一下
- 对数组排序,让重复元素位置相邻
- 规定重复元素的访问顺序,只能从左到右依次访问,违反了这个访问顺序,则认为可能造成重复
- 完整代码
public static List<List<Integer>> permuteUnique(int[] nums) {
List<Integer> item = new ArrayList<>();
List<List<Integer>> results = new ArrayList<>();
if (nums.length == 0){
results.add(item);
return results;
}
Arrays.sort(nums);
permuteUniqueHelper02(nums, new boolean[nums.length], item, results);
return results;
}
private static void permuteUniqueHelper02(int[] nums,
boolean[] visited,
List<Integer> item,
List<List<Integer>> results){
//一种非常朴素的想法 如果有重复 则去除
if (item.size() == nums.length){
results.add(new ArrayList<>(item));
return;
}
for (int i=0; i<nums.length; i++){
if (visited[i]){
continue;
}
//跳过重复元素
// 这里的处理和带重复元素的子集同样的思路 就是对于重复的元素 只能规定按顺序访问 不能跳跃
// 如果跳跃 则认为是会产生重复的情况 应该剔除
if (i!=0 && nums[i] == nums[i-1] && !visited[i-1]){
continue;
}
item.add(nums[i]);
visited[i] = true;
permuteUniqueHelper02(nums, visited, item, results);
item.remove(item.size() - 1);
visited[i] = false;
}
}