java 蓝桥杯 输出组合_Java蓝桥杯——排列组合

排列组合介绍

排列,就是指从给定n个数的元素中取出指定m个数的元素,进行排序。

e2f6a202a21af19aa8c646002efb8c48.png

组合,则是指从给定n个数的元素中仅仅取出指定m个数的元素,不考虑排序。

e6225b41744399caff71c41dde59dec1.png

全排列(permutation)

以数字为例,全排列就是从“第一个数字”起,“每个数字”分别与它“后面的数字”交换,复杂度为O(n!)

图示:

A依次和BC交换

交换一次后不急(如AB交换后,不急着交换AC),target后移,再依次交换

直到target=最后一个数时,停止,输出

返回上一步(很明显,用递归)接着做,此时注意,要把换了的数再还回来

java 蓝桥杯 输出组合_Java蓝桥杯——排列组合_第1张图片

代码:数组实现全排列

package hulaoshi.permutation;

public class Common {

static void swap(char str[], int a, int b) {

if (a == b) {

return;

}

char temp = str[a];

str[a] = str[b];

str[b] = temp;

}

static void printArr(char str[]) {

for (char c : str) {

System.out.print(c + " ");

}

System.out.println();

}

}

package hulaoshi.permutation;

public class 全排列 {

static int count = 0;

static void permutation(char str[], int t) {

if (t == str.length - 1) {

// 3.停止

System.out.print(++count + ": ");

Common.printArr(str);

return;

}

for (int i = t; i < str.length; i++) {

Common.swap(str, t, i);

// 2.递归

permutation(str, t + 1);

// 4.返回上层,换回来

Common.swap(str, t, i);

}

}

public static void main(String[] args) {

char str[] = new String("ABC").toCharArray();

// 1.从0开始

permutation(str, 0);

}

}

结果:

1: A B C

2: A C B

3: B A C

4: B C A

5: C B A

6: C A B

组合:数组实现

java 蓝桥杯 输出组合_Java蓝桥杯——排列组合_第2张图片

package hulaoshi.permutation;

public class 组合 {

static char[] _original = "ABCDE".toCharArray();

static int N = _original.length;

static int M = 3;

static int[] _indexArr = new int[M];

static void C(int n, int m) {

// 1.以5取3为例,n=5,m=3,遍历下标【2~4】,取第3个元素【m-1】

for (int i = m - 1; i <= n - 1; i++) {

// 2.下标存入

_indexArr[m - 1] = i;

if (m == 1) {

printArr();

// 4.不要return,循环还要继续

continue;

}

// 3.剩下的递归,剩下i个元素,取m-1个

C(i, m - 1);

}

}

static void printArr() {

for (int i : _indexArr) {

System.out.print(_original[i]);

}

System.out.println();

}

public static void main(String[] args) {

C(N, M);

}

}

结果:

ABC

ABD

ACD

BCD

ABE

ACE

BCE

ADE

BDE

CDE

排列:列表实现

就是一个数字一个数字地扫,为避免递归时,已经确定的数还回(如数组实现全排列时的两个swap,每次递归时创建一个新的ArrayList)

package hulaoshi.permutation;

import java.util.ArrayList;

public class 排列组合2 {

static char[] _原序列 = "ABC".toCharArray();

static int total;

static int n = _原序列.length;

static int m = 2;

static void printArray(ArrayList lstIdx) {

for (Integer i : lstIdx) {

System.out.print(_原序列[i]);

}

System.out.println();

}

static void A(int m, ArrayList lstIdx) {

if (m == 0) {

// 递归完毕,打印出来

printArray(lstIdx);

total++;

return;

}

for (int i = 0; i < n; i++) {

// 上一次调用本方法时的ArrayList,不改

// 创建新的ArrayList,为的是递归完毕时,旧的ArrayList不变

ArrayList lstIdx2 = new ArrayList();

lstIdx2.addAll(lstIdx);

if (!lstIdx.contains(i)) {

lstIdx2.add(i);

// 递归调用,将ArrayList传进去,但函数内会生成新的,把这个完全包含

A(m - 1, lstIdx2);

}

}

}

public static void main(String[] args) {

A(m, new ArrayList());

System.out.println("total : " + total);

}

}

结果:

AB

AC

BA

BC

CA

CB

total : 6

你可能感兴趣的:(java,蓝桥杯,输出组合)