算法之美-回溯法排列问题
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class Permutation {
static List<List<Integer>> res;
static int[] nums;
static boolean[] used;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
nums = new int[str.length()];
used = new boolean[str.length()];
for(int i=0;i<str.length();i++) {
char num = str.charAt(i);
nums[i] = num-'0';
nums[i] =Integer.valueOf(num-'0').intValue();
}
res = new ArrayList<>();
generatePermutation(nums,0,new LinkedList<>());
System.out.println(res.toString());
}
private static void generatePermutation(int[] nums, int index, LinkedList<Integer> p) {
// TODO Auto-generated method stub
if(index==nums.length) {
res.add((List<Integer>) p.clone());
return;
}
for(int i=0;i<nums.length;i++) {
if(!used[i]) {
used[i]=true;
p.addLast(nums[i]);
generatePermutation(nums,index+1,p);
p.removeLast();
used[i]=false;
}
}
return;
}
}
输出:
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
基本难点就是要去掉重复的
以这个[1,1,2]为例
正常会返回6个结果:其中第一行是以下标为0的1开始,而第二行是以下标为1的1开始。
1,1,2;1,2,1
1,1,2;1,2,1
2,1,1;2,1,1
去重做法就是,在dfs时要判断i和i-1是否相等和i-1这个值是否被用。
相等和没有被用就跳过这个i的情况,直接去i+1判断。
因为没被用的话,之后就可以再用这个i-1,那就会出现重复的情况。
比如说第二行是i=1时的判断,此时i和i-1的值相等,且i-1的值没被用
那么跳过i=1这个情况,直接去i=2,所以我们就去掉了第二行所有重复的。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class PermutationII {
static List<List<Integer>> res;
static int[] nums;
static boolean[] used;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
nums = new int[str.length()];
used = new boolean[str.length()];
for(int i=0;i<str.length();i++) {
char num = str.charAt(i);
nums[i] = num-'0';
nums[i] =Integer.valueOf(num-'0').intValue();
}
Arrays.sort(nums);
res = new ArrayList<>();
generatePermutation(nums,0,new LinkedList<>());
System.out.println(res.toString());
}
private static void generatePermutation(int[] nums, int index, LinkedList<Integer> p) {
// TODO Auto-generated method stub
if(index==nums.length) {
res.add(new ArrayList<>(p));
return;
}
for(int i=0;i<nums.length;i++) {
if(used[i]||(i>0&&nums[i-1]==nums[i]&&used[i-1]==false)) {
continue;
}
if(!used[i]) {
used[i]=true;
p.addLast(nums[i]);
generatePermutation(nums,index+1,p);
p.removeLast();
used[i]=false;
}
}
return;
}
}
输出: