输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义: 已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存在p (1 <= p <= k),使得 s1 = t1, s2 = t2, ..., sp - 1 = tp - 1, sp < tp成立。 每组样例输出结束后要再输出一个回车。
abc
abc acb bac bca cab cba
// 可以将其想像成竖着排列的组
// 例如
// a a a
// b b b
// c c c
// 第一组先取 a,标记数组标记为 true,代表已访问过
// 然后递归调用
// 第二组由于 a 标记为 true 跳过 取 b
// 以此类推
// 第三组结束后输出
// 此时再依次将每一组用过的还原为 true
// 访问到第几组由调用栈决定,每一组访问到第几个由 for 循环 i 决定,一次排列中是否访问过由 tag 数组决定
private static void get(char[] s, int index, boolean[] tag, char[] out) {
// 访问结束
if (index == s.length) {
System.out.println(out);
return;
}
for (int i = 0; i < s.length; i++) {
// 没有访问过
if (!tag[i]) {
out[index] = s[i];
// 第一组内已访问过
tag[i] = true;
get(s, index + 1, tag, out);
// 将访问过的还原
tag[i] = false;
}
}
} import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {
static boolean[] visited;
static char[] array;
static ArrayList<String> list = new ArrayList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
array = scanner.next().toCharArray();
visited = new boolean[array.length];
gen(0,"");
Collections.sort(list);
for (String s1 : list) System.out.println(s1);
//注意题目要求:每组样例输出结束后要再输出一个回车。
System.out.println();
}
static void gen(int step,String cur){
// 递归终止
if (step==array.length){
list.add(cur);
return;
}
for (int i = 0; i <array.length ; i++) {
if (!visited[i]){
visited[i]=true;
gen(step+1,cur+array[i]);
// 回溯,清除现场
visited[i]=false;
}
}
}
} import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
char[] input = reader.next().toCharArray();
Arrays.sort(input);
ArrayList<Character> path = new ArrayList<>();
boolean[] visited = new boolean[input.length];
helper(input, path, visited);
System.out.println();
}
public static void helper(char[] str, ArrayList<Character> path, boolean[] visited) {
if (path.size() == str.length) {
for (char c: path) {
System.out.print(c);
}
System.out.println();
return;
}
for (int i = 0; i < str.length; ++i) {
if (visited[i])
continue;
path.add(str[i]);
visited[i] = true;
helper(str, path, visited);
path.remove(path.size()-1);
visited[i] = false;
}
}
} //用dfs写的,主要是排序和去重吧
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
testFullArrMent();
}
static boolean[] flag;
static List<String> list = new ArrayList<String>();
public static void testFullArrMent(){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] ch = s.toCharArray();
char[] c = new char[ch.length];
flag = new boolean[ch.length];
dfs(ch,c,0);
Collections.sort(list);
for(String str:list){
System.out.println(str);
}
System.out.println();
}
private static void dfs(char[] ch, char[] c, int k) {
// TODO Auto-generated method stub
if(k==ch.length){
String s = String.valueOf(c);
if(!list.contains(s)){
list.add(s);
}
}
for(int i=0;i<ch.length;i++){
if(!flag[i]){
flag[i]=true;
c[k]=ch[i];
dfs(ch,c,k+1);
flag[i]=false;
}
}
}
} import java.util.Arrays;
import java.util.Scanner;
/*
* 思路:
* 当我试着分解问题时,发现,n个数(a1,...,an)的全排列可以分解为a1拼接(n-1)个数全排列.直到1个数的全排列.此时能够确定某一个排列.
* 自然会去尝试一下递归处理
* # 那么思考递归变量是哪些呢?
* 1. 参与全排列的元素在变,用char[]数组变量表示
* 2. 因为要打印完整的全排列,每次父问题分为前后两半之后,前半边字符串需要传递进来和后半边字符串进行拼接,然后打印.
*
* # 递归的边界条件是什么呢?
* 1. 我们能直观感受到只有一个数时,问题不能再分解,并且可以拼接,打印字符串了.
* 2. 但是,我们可能要用递归变量来具体化边界情况. recursive(前半边字符串=不怎么好描述...,char[] = 1个元素(这个1很好确定),);
*
* # 打印的顺序满足字典序吗?
* 卧槽,是满足的.
*/
public class Main_Sure {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
char[] input = scanner.nextLine().toCharArray();
Arrays.sort(input);//有坑,存在"dbc"这种顺序打乱的test case,所以排个序.
fullPermutation("", input);
System.out.println();
}
}
public static void fullPermutation(String pre, char[] inputs) {
if (inputs.length == 1) {
System.out.println(pre.toString() + inputs[0]);
return;
}
//分类计数原理计算全排列的排列个数: 每个字符都要做一次开头. 这样分类完备,无重复.
//inputs[i]:某全排列开头的字符.
for (int i = 0; i < inputs.length; i++) {
char[] rest = new char[inputs.length - 1];
int index = 0;
for (int j = 0; j < inputs.length; j++) {
if (i != j) {
rest[index++] = inputs[j];
}
}
fullPermutation(pre +""+inputs[i], rest);
}
}
}