117.info
人生若只如初见

Java实现全排列的三种算法详解

全排列是一种非常常见的排列问题,即给定一个数组,需要将其所有元素进行全排列,即将数组中的元素进行全排列得到新的数组。

下面介绍三种常见的全排列算法的实现。

1.递归算法:

递归算法是一种非常直观的全排列算法,其基本思想是将数组中的第一个元素与其它元素进行交换,然后对剩余的元素进行全排列,直到只剩下一个元素为止。

具体实现如下:

public class Permutations {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
permute(nums);
}
public static void permute(int[] nums) {
permute(nums, 0, nums.length - 1);
}
private static void permute(int[] nums, int l, int r) {
if (l == r) {
printArray(nums);
} else {
for (int i = l; i <= r; i++) {
swap(nums, l, i);
permute(nums, l + 1, r);
swap(nums, l, i); // 还原数组
}
}
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private static void printArray(int[] nums) {
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
}
}

2.字典序算法:

字典序算法是另一种常见的全排列算法,其基本思想是通过字典序来生成全排列。首先将数组按照字典序排序,然后不断生成下一个排列,直到所有的排列都生成完毕。

具体实现如下:

public class Permutations {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
permute(nums);
}
public static void permute(int[] nums) {
Arrays.sort(nums);
printArray(nums);
while (nextPermutation(nums)) {
printArray(nums);
}
}
private static boolean nextPermutation(int[] nums) {
int i = nums.length - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--;
}
if (i >= 0) {
int j = nums.length - 1;
while (nums[j] <= nums[i]) {
j--;
}
swap(nums, i, j);
}
reverse(nums, i + 1);
return i >= 0;
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private static void reverse(int[] nums, int start) {
int i = start, j = nums.length - 1;
while (i < j) {
swap(nums, i, j);
i++;
j--;
}
}
private static void printArray(int[] nums) {
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
}
}

3.回溯算法:

回溯算法是一种非常灵活的全排列算法,其基本思想是通过递归的方式生成全排列。具体实现如下:

public class Permutations {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
permute(nums);
}
public static void permute(int[] nums) {
List> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), nums);
for (List list : result) {
printList(list);
}
}
private static void backtrack(List> result, List tempList, int[] nums) {
if (tempList.size() == nums.length) {
result.add(new ArrayList<>(tempList));
} else {
for (int i = 0; i < nums.length; i++) {
if (tempList.contains(nums[i])) {
continue;
}
tempList

未经允许不得转载 » 本文链接:https://www.117.info/ask/fe2c5AzsLBg9WBFU.html

推荐文章

  • java构造方法有哪些特点

    以下是Java构造方法的特点: 构造方法的名称必须与类的名称完全相同。 构造方法没有返回类型,包括void类型。 构造方法在类被实例化时自动调用,用于初始化对象的...

  • java方法重写和重载的区别是什么

    Java方法重写(Override)和重载(Overload)是面向对象编程中的两个重要概念,它们的区别如下: 定义:重写是指在子类中重新实现父类中已存在的方法,方法名、参...

  • java怎么让编译不报错

    要让Java编译不报错,你需要确保以下几点: 语法错误:检查代码中的拼写错误、缺少分号、括号不匹配等语法问题,并进行修正。 类型错误:确保变量的类型匹配,比...

  • java中Pattern.compile()报错问题怎么解决

    要解决Java中Pattern.compile()方法报错的问题,可以遵循以下步骤: 检查正则表达式是否正确:首先,确保你提供的正则表达式语法是正确的。你可以使用在线正则表...

  • iframe窗口高度自适应的实现方法

    要实现iframe窗口高度自适应,可以通过以下方法: 使用JavaScript动态调整iframe的高度: 在iframe加载完成后,通过获取iframe的内容高度并设置给iframe的高度。...

  • MySQL存储过程及语法详解

    存储过程是一组预编译的SQL语句,可以在MySQL数据库中被保存和重复调用。存储过程可以接受输入参数,并返回多个结果。
    MySQL存储过程语法如下:
    CREAT...

  • Web应用中设置Context Path案例详解

    在Web应用中,Context Path指的是Web应用的上下文路径。它是URL中的一部分,用于区分不同的Web应用。具体来说,Context Path是Web服务器将Web应用映射到URL路径的...

  • Java ArrayAdapter用法案例详解

    ArrayAdapter是Android中常用的数据适配器,用于将数据源绑定到ListView、GridView等控件上。下面是一个使用ArrayAdapter的示例,详细解释了使用方法:
    首先...