一、迭代法
代码块:
import java.util.ArrayList;
public class 全排列Ⅰ {
public static void main(String[] args) {
ArrayList<String> res = new ArrayList<String>();
res = f("abc");
System.out.println(res.size());
System.out.println(res);
}
//迭代法
public static ArrayList<String> f(String A){
int len = A.length();//n:集合A的长度
ArrayList<String> res = new ArrayList<String>();
res.add(A.charAt(0) + "");//添加第一个元素
//第二个字符插入到前面生成集合的每个元素里面
for(int i = 1; i < len; i++){
ArrayList<String> resNew = new ArrayList<String>();
char c = A.charAt(i);//c:字符串A第二个字符……
for(String str : res){
//插入到每个位置,形成一个新串
String newStr = c + str;//加在前面
resNew.add(newStr);
newStr = str + c;//加在后面
resNew.add(newStr);
//加在中间
for(int j = 1; j < str.length(); j++){
newStr = str.substring(0, j) + c + str.substring(j);
resNew.add(newStr);
}
}
res = resNew;//更新
}
return res;
}
}
运行结果:
6
[cba, bac, bca, cab, abc, acb]
二、交换法
代码块:
import java.util.ArrayList;
public class 全排列Ⅱ {
static ArrayList<String> res = new ArrayList<String>();
public static void main(String[] args) {
String s = "abcd";//字符串
char arr[] = s.toCharArray();//字符串数组
res = f(arr, 0);//全排列
System.out.println(res.size());//输出排序总数
System.out.println(res);//输出排序结果
}
//交换法(不按字典序)
static ArrayList<String> f(char arr[], int k){
//保存每次排完序的结果
if(k == arr.length){
res.add(new String(arr));
}
//从k位开始的每个字符,都尝试放在新排列的k这个位置(k:0 1 2)
for(int i = k; i < arr.length; i++){
swap(arr, k, i);//把后面每个字换到k位
f(arr, k+1);//递归每种字符放在首位的情况
swap(arr, k, i);//回溯,换回来
}
return res;
}
//交换数组arr中下标位i和下标为j的字符
static void swap(char arr[], int i, int j){
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
运行结果:
24
[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab, cdba, dbca, dbac, dcba, dcab, dacb, dabc]
三、前缀法
代码块:
public class 全排列Ⅲ {
public static void main(String[] args) {
String s = "abc";
char ch[] = s.toCharArray();
f("", ch);
System.out.println("\n出现次数:"+count);
}
//前缀法(符合字典序)
static int count = 0;
static void f(String s, char arr[]){
//前缀的长度 = 字符集的长度,一个排列就完成了
if(s.length() == arr.length){
count++;
System.out.print(s+" ");
}
//每次都从头扫描,只要该字符可用,我们就附加到前缀后面,前缀变长
for(int i = 0; i < arr.length; i++){
char ch = arr[i];
//这个字符可用:在该方法中出现次数 < 在字符集中的出现次数
if(count(s.toCharArray(), ch) < count(arr, ch)){
f(s+ch, arr);
}
}
}
//判断字符数组中字符ch的出现次数
static int count(char arr[], char ch){
int cnt = 0;
for(char c : arr){
if(c == ch)cnt++;
}
return cnt;
}
}
运行结果:
abc acb bac bca cab cba
出现次数:6