【Java/算法/排列】ABCDE五人排一排,如果AB必相邻且B在A的右边,那么不同的排法有几种?
【数学解法】
AB捆绑,内部不再排序,与CDE全排,得A44=24种排法。
【代码解法】
Fiveman类:
package test230425; import java.util.List; import arrange.Arranger; /** * ABCDE五人排一排,如果AB必相邻且B在A的右边,那么不同的排法有几种?列举出这些排法。 */ public class Fiveman { public static void main(String[] args) { final String[] names = { "AB", "C", "D", "E" }; final int[] arr = { 0, 1, 2, 3 }; Arranger arranger = new Arranger(arr); int idx = 0; for (List<Integer> res : arranger.getResults()) { String name = ""; for (int i = 0; i < names.length; i++) { name += names[res.get(i)]; } System.out.println(String.format("%02d", ++idx) + "." + name); } } }
Arranger类:
package arrange; import java.util.ArrayList; import java.util.List; /** * 用于产生数组全排列结果的工具类 * @since 2023/4/21 */ public class Arranger { // 保存在内部的原始元素数组的引用 private int[] rawArr; // 返回结果 private List<List<Integer>> results; /** * 构造函数 * * @param raws 原始元素数组 */ public Arranger(int[] raws) { rawArr = raws; results = new ArrayList<>(); doArrange(new ArrayList<>()); } /** * 使用递归进行全排列,结果放在results中 * * @param initialList 初始链表 */ private void doArrange(List<Integer> initialList) { List<Integer> innerList = new ArrayList<>(initialList); if (rawArr.length == initialList.size()) { results.add(innerList); } for (int i = 0; i < rawArr.length; i++) { if (innerList.contains(rawArr[i])) { continue; } innerList.add(rawArr[i]); doArrange(innerList); innerList.remove(innerList.size() - 1); } } /** * 获得结果链表的引用 * * @return */ public List<List<Integer>> getResults() { return results; } // 测试 public static void main(String[] args) { int[] numbers = { 1, 2, 3,4,5}; Arranger arranger = new Arranger(numbers); int idx = 0; for (List<Integer> re : arranger.getResults()) { System.out.println(String.format("%02d", ++idx) + "." + re); } } }
【排序结果】
01.ABCDE 02.ABCED 03.ABDCE 04.ABDEC 05.ABECD 06.ABEDC 07.CABDE 08.CABED 09.CDABE 10.CDEAB 11.CEABD 12.CEDAB 13.DABCE 14.DABEC 15.DCABE 16.DCEAB 17.DEABC 18.DECAB 19.EABCD 20.EABDC 21.ECABD 22.ECDAB 23.EDABC 24.EDCAB
END