文章目录
1.排列
从char[ ] arr数组中进行排列出 n位数(长度)的字符串(n<=arr.length)。
a.不带注释:
public class test5 {
public static void main(String[] args) {
char[] arr = new char[] {'1','2','3','4','5','6','7','8','9'};
n = 9;
v(arr,0);
}
static int n;
static StringBuilder builder = new StringBuilder();
public static void v(char[] arr,int count) {
if(count==n) {
System.out.println(builder.toString());
return;
}
for(int i=0;i<arr.length;i++) {
if(builder.indexOf(""+arr[i])==-1){
builder.insert(count, arr[i]);
v(arr,count+1);
builder.delete(count, builder.length());
}
}
}
}
b.带注释:
public class Main {
public static void main(String[] args) {
// 开始时间
long start = System.currentTimeMillis();
// 调用方法
char[] arr = new char[] {'1','2','3','4','5','6','7','8','9'}; // 使用char数组,可以对任意字符进行排列
n = 9; // 排列9位数
/**
* 每一层的数字都有可能是1-9,当某一层的数字在已有的StringBuilder中没有时,即可选.
* builder = "138945";
* builder = "1389572";
* builder = "138957246";
* builder = "138957246";
* // 满足输出,退回上一层 "13895724",继续从for循环i=7开始往下走,末找到符合的数,结束当前层数,
* // 继续即回上层 "1389572" 继续从for循环i=5开始往下走,找到6。"13895726",进入下一层
* // 找到 "4"。"138957264",到达第n层,输出.
*/
v(arr,0);
// 结束时间
long end = System.currentTimeMillis();
System.out.println("排列总数: "+k);
System.out.println("时间: "+(end-start)+"ms");
// 1484-1820ms
}
static int n; // 需要排列的字符个数,如 排列:4位数(1234),5位数(34567)
static StringBuilder builder = new StringBuilder(); // 存放排列好的字符串
static int k = 0; // 统计排列的字符组数量
public static void v(char[] arr,int count) {
// count: 从0开始递归,每一层生成一个数,进行n层递归生成n位排列数
if(count==n) {
// 输出该排列好的字符组
System.out.println(builder.toString());
k++;
// 结束当前方法,返回上一层往下查找排列。
return;
}
// 查找排列,从下标0开始,获取字符arr[i]
for(int i=0;i<arr.length;i++) {
// 若字符arr[i]不存在于arr数组前面已有的数,即满足
if(builder.indexOf(""+arr[i])==-1){
// 插入到位置count中(这里可以用builder.replace方法替换,同时省去delete方法)
builder.insert(count, arr[i]);
// 进行下一层,即count+1
v(arr,count+1);
// 删除上一次排列好第count之后的字符
builder.delete(count, builder.length());
}
}
}
}
2.组合
从char[ ] arr数组中组合出 n位数(长度)的字符串
a.不带注释:
public class test6 {
public static void main(String[] args) {
char[] arr = new char[] {'1','2','3','4','5','6','7'};
v(arr,0,0);
}
static int n = 4;
static StringBuilder builder = new StringBuilder();
public static void v(char[] arr,int count,int start) {
if(count==n) {
System.out.println(builder.toString());
return;
}
for(int i=start;i<arr.length;i++) {
builder.insert(count, arr[i]);
v(arr,count+1,i+1);
builder.delete(count, builder.length());
}
}
}
b.带注释:
public class test6 {
public static void main(String[] args) {
// 同样是char[]数组
char[] arr = new char[] {'1','2','3','4','5','6','7'};
/**
* 例:从arr数组中组合出 4位数(n=4)
* 第一个数(层)是 0-4 (start)-(length-n+count+1)
* 第二个数是 1-5 (start+1)-(length-n+count+1)
* 第三个数是 2-6 ...
* 第四个数是 3-7 ....
* 综上,每一层的可选的数的范围是{i,arr.length-n+count+1}
* i是上一层已组合进去的数+1,i初始为0
*/
v(arr,0,0);
}
static int n = 4; // 组合 4位数
static StringBuilder builder = new StringBuilder(); // 存放组合好的字符串
// 参数count用于记录所在的层数
// 参数start用于for循环初始位置,因为下一个数肯定是在上一个数之后产生,如:已有 12或 14,
// 那么下一个数(第三个数)肯定是大于 2或 4
public static void v(char[] arr,int count,int start) {
// 到达第n层即已经组合好 4位数的字符串
if(count==n) {
// 输出
System.out.println(builder.toString());
// 结束当前方法
return;
}
// start开始的位置在上一个数之后,start在调用该方法时赋值为0,即第一个数从char[0] = 1 开始
for(int i=start;i<arr.length;i++) {
// 插入
builder.insert(count, arr[i]);
// 下一层
v(arr,count+1,i+1);
// 删除
builder.delete(count, builder.length());
}
}
}