您的位置:首页 > 其它

递归专题-排列组合问题

2018-01-17 10:23 295 查看
问题描述:输入一个字符串,然后将字符串所有字符排列组合,输出排列组合后的所有可能。

思路:把一个字符串看成两个部分,第一部分是它的第一个字符,第二部分是它后边的所有字符。求所有排列的过程可看做两步,第一步求所有可能出现在第一个位置的字符,即把第一个字符和后面的所有字符交换(注:并不是一次找出来全部,而是找出来一个,就执行第二步,找出以这个字符开始的全部排列,第一步通过循环遍历实现)。

第二步固定第一个字符,求后面所有字符的排列,此时仍把后面所有字符分成上述的两部分,然后递归处理。找出全部排列后还要之前交换的字符交换回去,保证找到的第一个位置不重复。注意本题考虑了去重复问题,即相同排列只显示一次,方法是在交换第一个元素和后边的元素时,如果值相等就不交换,或者后边这个值在之前位置出现过(说明曾经交换过),也不交换。

package zhuanti.digui;

import java.util.Arrays;
import java.util.Scanner;

/**
* 给一个字符串,然后把这个字符串重新排列组合,列出所有可能
*/
public class Pailiewenti {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入要进行全排列的字符串:");
String s=sc.nextLine();
Permutation(s.toCharArray());
sc.close();
}
public static void Permutation(char[] str){
if(str==null)
return;
int begin=0;
Permutation(str, begin);
}
public static void Permutation(char[] str,int begin){
if(begin+1==str.length){//遍历完一遍字符串,打印输出一次,返回
//System.out.println(String.valueOf(str));
System.out.println(Arrays.toString(str));
}
else{
for(int i=begin;i<str.length;i++){
if(notSame(str,begin,i)){//去重判断,如果当前字符和后边的字符一样,或者后边字符在之前出现过,不交换。第一次自己和自己换除外。
//1,可能出现在第一个位置的字符,即交换第一个字符和后边所有字符,第一次是自己和自己交换
swap(str,begin,i);
//2,固定第一个字符,递归求后面所有字符的排列
Permutation(str, begin+1);
//3,递归处理完后边的字符后,记得把前边交换的字符再换回来,保证第一个位置的字符不重复
swap(str,begin,i);

}
}
}
}
public static boolean notSame(char[] str,int begin,int end){
for(int j=begin;j<end;j++){
if(str[j]==str[end]){
return false;
}
}
return true;
}
public static void swap(char[] str,int a,int b){
char temp = str[a];
str[a] = str[b];
str[b] = temp;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 递归 排列组合