如果给定一个字符串,如何打印出其全排列呢?
如果在C++ 中可以直接用next_permutation库函数,但是Java中并没有这样的库函数,需要手动写出算法。
1.问题描述:
一组字符串的全排列,按照全排列的顺序输出,并且每行结尾无空格。
2.输入:
输入一个字符串
3.输入示例:
abc
4.输出示例:
abc
acb
bac
bca
cba
cab
全排列的基本思想是: 把待全排列记录分为两个部分: (1) 第一个记录 (2) 剩下的所有元素
所有记录的全排列就是所有可能出现在第一个位置的记录与剩下所有元素的全排列。 以[1,2,3]为例, 1,2,3的全排列可以看作是
1,[2,3的全排列]
[2,3]的全排列又可以看作是
2,[3的全排列]—————对应123
3,[2的全排列]—————对应132 2,[1,3的全排列]
[1,3]的全排列又可以看作是
1,[3的全排列]—————对应213
3,[1的全排列]—————对应231 3,[1,2的全排列]
[1,2]的全排列又可以看作是
1,[2的全排列]—————对应312
2,[1的全排列]—————对应321所以很明显,这就是一个递归的思想:给你部分记录,全排列就是所有可能出现在第一个位置的记录与剩下的元素的全排列,剩下的元素的全排列又是剩下的可能出现在第一个位置的元素与剩下的元素的全排列,依次重复下去….
以上内容引用自月光下一只赏月的猪的博客,原文: 传送门
其实,Java中实现排列都是差不多的“套路”,废话少说,直接上代码:
import java.util.Scanner;
public class Permutation {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String string = scanner.nextLine();
char[] cs = string.toCharArray();
permutation(cs ,0);
}
//确认某个排列的第k位
private static void permutation(char[] arr, int k) {
//全部确认
if (k == arr.length) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
System.out.println();
}
//选定第k位
for (int i = k; i < arr.length; i++) {
//将第i位和第k位交换
char temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
//移交下一层确认k+1位
permutation(arr, k+1);
//回溯
temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
}
}
下面给出几个相关的类型题,帮助大家加深一下印象:
- 扑克序列 题解传送门
标题:扑克序列
A A 2 2 3 3 4 4, 一共4对扑克牌。请你把它们排成一行。 要求:两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌。 请填写出所有符合要求的排列中,字典序最小的那个。
例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。
请通过浏览器提交答案。“A”一定不要用小写字母a,也不要用“1”代替。字符间一定不要留空格。
- 带分数 题解传送门
标题:带分数
100 可以表示为带分数的形式:100 = 3 + 69258 / 714 还可以表示为:100 = 82 + 3546 / 197 注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。 类似这样的带分数,100 有 11 种表示法。
题目要求: 从标准输入读入一个正整数N (N<1000*1000) 程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!例如: 用户输入: 100 程序输出: 11
再例如: 用户输入: 105 程序输出: 6
资源约定: 峰值内存消耗(含虚拟机) < 64M CPU消耗 < 3000ms