如何用Java实现排列组合算法

下面是关于如何用Java实现排列组合算法的完整攻略:

排列组合算法实现

什么是排列与组合

排列是指选出m个元素,一次排成一个列,有序的称为$m$的排列,记为$A_m^n$

组合是指选出m个元素,无序的称为${m}$的组合,记作$C_m^n$

可以发现,排列与组合的关联非常大,在代码实现中,它们也是联系在一起的。

排列算法实现

递归算法

通过递归实现简单,下面为排列递归实现代码:

public static void permutation(char[] arr, int start, int end) {
    if (start == end) { 
        System.out.println(Arrays.toString(arr));
    } else {
        for (int i = start; i <= end; i++) {
            swap(arr, start, i);
            permutation(arr, start + 1, end);
            swap(arr, start, i);
        }
    }
}

public static void swap(char[] arr, int i, int j) {
    char temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

该算法的时间复杂度为$O(n!)$,极其耗时。

非递归算法

非递归算法采用字典序法,可以将排列算法的时间复杂度降低到$O(n^2)$。

核心代码如下:

public static void nonRecPermutation(char[] arr) {
    Arrays.sort(arr);
    System.out.println(Arrays.toString(arr));
    while (true) {
        int i, j;
        // 找到逆序区域的头部(在末尾找到第一个升序的元素)
        for (i = arr.length - 2; i >= 0; i--) {
            if (arr[i] < arr[i + 1]) {
                break;
            }
            if (i == 0) {
                return;
            }
        }
        // 找到头部后面的最小升序元素
        for (j = arr.length - 1; j > i; j--) {
            if (arr[j] > arr[i]) {
                break;
            }
        }
        // 交换头尾元素
        swap(arr, i, j);
        // 翻转逆序区域
        reverse(arr, i + 1, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
}

public static void reverse(char[] arr, int start, int end) {
    while (start < end) {
        swap(arr, start, end);
        start++;
        end--;
    }
}

组合算法实现

组合算法首先有一个求$C_n^m$的公式:

$$C_n^m=\frac{n!}{(n-m)!m!}$$

其实我们不必求出所有的组合,只需要找到第$k$个组合就行了,可以使用递归实现。

组合的递归实现代码如下:

public static void combination(char[] arr, int m, int start, char[] result, int index) {
    if (index == result.length) {
        System.out.println(Arrays.toString(result));
    } else {
        for (int i = start; i <= arr.length - m + index; i++) {
            result[index] = arr[i];
            combination(arr, m, i + 1, result, index + 1);
        }
    }
}

该算法的时间复杂度为$O(C_n^m)$。

示例

下面为排列和组合的示例代码:

public static void main(String[] args) {
    char[] arr = {'a', 'b', 'c'};
    // 排列
    permutation(arr, 0, arr.length - 1);
    nonRecPermutation(arr);
    // 组合
    char[] result = new char[2];
    combination(arr, 2, 0, result, 0);
}

以上就是用Java实现排列组合算法的方法,包括排列的递归和非递归实现以及组合的递归实现。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:如何用Java实现排列组合算法 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 一个开发人员眼中的JSP技术(上)

    下面是一个详细的攻略: 什么是JSP技术? JSP(JavaServer Pages)是一种基于Java语言的web开发技术,它是由Servlets衍生出来的一种技术。它允许将Java代码插入到HTML页面中,使得页面具备动态生成内容的能力。相比于Servlets,JSP技术更加容易开发,并且更适合于构建动态网站。这是因为在JSP中可以通过EL表达式、自定义…

    Java 2023年6月15日
    00
  • Spring Boot超详细分析启动流程

    Spring Boot是基于Spring框架的一种快速开发框架,它通过自动化配置和约定大于配置的方式,可以快速的搭建一个Web应用。 Spring Boot启动流程主要分为三个阶段:准备阶段、上下文创建阶段、启动阶段。 准备阶段 Spring Boot准备阶段主要是读取应用程序的配置文件,获取配置文件中自定义的配置内容,并为后续的启动做好一些准备工作。准备阶…

    Java 2023年5月19日
    00
  • java如何实现判断文件的真实类型

    Java如何实现判断文件真实类型的攻略如下: 1.使用后缀名判断文件类型 Java可以通过文件后缀名来判断文件类型。例如,如果文件名以”.txt”结尾,则是文本文件。这种方法适用于大多数文件类型,但不适用于所有文件。以下是示例代码: import java.io.File; public class FileTypeChecker { public stat…

    Java 2023年5月19日
    00
  • 世界著名程序SpringMVC完整过程

    以下是关于“世界著名程序SpringMVC完整过程”的完整攻略,其中包含两个示例。 1. 前言 SpringMVC是一种常用Java Web开发框架,其核心思想是基于MVC模式来实现Web应用程序的开发。本攻略将详细讲解SpringMVC的完整过程,帮助读者深入理解SpringMVC框架的工作原理。 2. SpringMVC完整过程 以下是SpringMVC…

    Java 2023年5月16日
    00
  • Java中后台线程实例解析

    Java中后台线程实例解析 在Java中,线程可以分为前台线程和后台线程。前台线程是指主线程,后台线程是指与主线程并行执行但不会阻止主线程正常结束的线程。本文将详细讲解Java中后台线程的使用方法和示例说明。 后台线程的创建与启动 后台线程可以通过继承Thread类并覆盖run()方法来创建和启动。具体过程如下: public class Backgroun…

    Java 2023年5月18日
    00
  • 解决SpringMVC、tomcat、Intellij idea、ajax中文乱码问题

    下面是 SpringMVC、Tomcat、Intellij IDEA 以及 Ajax 中文乱码问题的完整攻略。 1. SpringMVC 乱码问题解决 1.1. SpringMVC 中文乱码示例 示例代码如下: @RequestMapping("/hello") @ResponseBody public String hello(@Req…

    Java 2023年5月20日
    00
  • Spring security认证两类用户代码实例

    下面是详细讲解“Spring security认证两类用户代码实例”的完整攻略。 1. Spring Security认证两类用户 Spring Security可以认证两类用户:前台用户和后台用户。在实际开发中,这两类用户需要分别进行认证,才能保证系统的安全性。 1.1 前台用户 前台用户是指普通用户,通常需要进行注册、登录等操作。Spring Secur…

    Java 2023年5月20日
    00
  • Java Apache Commons报错“SAXNotRecognizedException”的原因与解决方法

    “SAXNotRecognizedException”是Java的Apache Commons类库中的一个异常,通常由以下原因之一引起: 无效的SAX属性:如果SAX属性无效,则可能会出现此错误。在这种情况下,需要检查SAX属性以解决此问题。 无效的SAX特性:如果SAX特性无效,则可能会出现此错误。在这种情况下,需要检查SAX特性以解决此问题。 以下是两个…

    Java 2023年5月5日
    00
合作推广
合作推广
分享本页
返回顶部