这里是求解A(n, 3),在代码里面可以修改递归出口的条件if(k == 2),把2改成别的数来解决,当k=n时,就是全排列了:
public class Test {
//递归求出排列组合A(n, 3)
private void recurse(int k, ArrayList<Integer> mp,
ArrayList<ArrayList<Integer>> allList, ArrayList<Integer> list, HashSet<Integer> already){
for(int i = 0; i < mp.size(); i++){
ArrayList<Integer> nowList = new ArrayList<>(list);
HashSet<Integer> nowAready = new HashSet<>(already);
if(already.contains(mp.get(i))){//去除前面重复的排过的数
continue;
}
if(k == 2){//递归出口,单独把后面的加完,否则会漏解
for(int m = 0; m < mp.size(); m++){
if(already.contains(mp.get(m))){
continue;
}
nowList = new ArrayList<>(list);
nowList.add(mp.get(m));
//System.out.println("k: " + k + " nowlist.size: " + nowList.size());
allList.add(nowList);
}
return;
}
else{
nowList.add(mp.get(i));
nowAready.add(mp.get(i));
//System.out.println("k: " + k + " nowlist.size: " + nowList.size());
recurse(k + 1, mp, allList, nowList, nowAready);
}
}
}
public static void main(String[] args){
ArrayList<Integer> now = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
ArrayList<Integer> list = new ArrayList<>();
HashSet<Integer> already = new HashSet<>();
ArrayList<ArrayList<Integer>> allList = new ArrayList<>();
Test test = new Test();
test.recurse(0, now, allList, list, already);
System.out.println("所有的排列数:" + allList.size());
for(int i = 0; i < allList.size(); i++){
list = allList.get(i);
for(int k = 0; k < list.size(); k++){
System.out.print(list.get(k) + " ");
}
System.out.println();
}
}
}
运行结果:
所有的排列数:60
1 2 3
1 2 4
1 2 5
1 3 2
1 3 4
1 3 5
1 4 2
1 4 3
1 4 5
1 5 2
1 5 3
1 5 4
2 1 3
2 1 4
2 1 5
2 3 1
2 3 4
2 3 5
2 4 1
2 4 3
2 4 5
2 5 1
2 5 3
2 5 4
3 1 2
3 1 4
3 1 5
3 2 1
3 2 4
3 2 5
3 4 1
3 4 2
3 4 5
3 5 1
3 5 2
3 5 4
4 1 2
4 1 3
4 1 5
4 2 1
4 2 3
4 2 5
4 3 1
4 3 2
4 3 5
4 5 1
4 5 2
4 5 3
5 1 2
5 1 3
5 1 4
5 2 1
5 2 3
5 2 4
5 3 1
5 3 2
5 3 4
5 4 1
5 4 2
5 4 3