全排列的概念
全排列,又称排列组合,是指从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排成一列的所有可能的情况,全排列的计算公式为:P(n, m) = n! / (n m)!,其中n!表示n的阶乘,即n*(n-1)*...*1。
Java实现全排列的三种算法
1、递归法
递归法是最简单的实现全排列的方法,基本思路是从第一个元素开始,依次选取剩余元素中的一个与当前元素进行交换,然后对剩余元素进行全排列,递归终止条件是当只剩下一个元素时,直接输出这个元素。
public class Permutations { public static void main(String[] args) { int[] nums = {1, 2, 3}; permute(nums); } public static void permute(int[] nums) { if (nums == null || nums.length == 0) { return; } boolean[] used = new boolean[nums.length]; backtrack(nums, used, 0); } private static void backtrack(int[] nums, boolean[] used, int first) { if (first == nums.length) { for (int i = 0; i < nums.length; i++) { System.out.print(nums[i] + " "); } System.out.println(); return; } for (int i = 0; i < nums.length; i++) { if (used[i]) { continue; } used[i] = true; swap(nums, first, i); backtrack(nums, used, first + 1); used[i] = false; swap(nums, first, i); } } }
2、回溯法(迭代版)
回溯法是一种更加高效的实现全排列的方法,它利用了动态规划的思想,将问题分解为子问题,在每一步选择一个元素时,都尝试将其与其他元素交换位置,然后继续求解下一层的全排列,如果当前层无法进行全排列,说明下一层也不存在全排列的可能,此时需要回溯到上一层重新选择元素。
public class IterativePermutations { public static void main(String[] args) { int[] nums = {1, 2, 3}; permute(nums); } public static void permute(int[] nums) { boolean[] used = new boolean[nums.length]; backtrack(nums, used); } private static void backtrack(int[] nums, boolean[] used) { List<Integer> results = new ArrayList<>(); dfs(nums, used, new ArrayList<>(), results); System.out.println(results); } private static void dfs(int[] nums, boolean[] used, List<Integer> path, List<List<Integer>> results) { if (path.size() == nums.length) { results.add(new ArrayList<>(path)); return; } for (int i = 0; i < nums.length; i++) { if (used[i]) { continue; } used[i] = true; path.add(nums[i]); dfs(nums, used, path, results); path.remove(path.size() 1); used[i] = false; } } }
3、Heap排序法结合生成函数法(空间换时间)
Heap排序法是一种基于堆的排序算法,它可以高效地找到序列中的最大值或最小值,生成函数法是一种用于生成全排列的算法,它可以将全排列问题转化为一个有序数组的问题,通过使用Heap排序法和生成函数法相结合,可以实现更高效的全排列计算。
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/194688.html