给定一个序列,输出无重复,且按字典序的全排列——字典序算法

题目描述

题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。
例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

  • 重排序
  • 从右到左找到正序对
  • 从右到左找到第一个比正序对第一个元素大的元素
  • 交换那两个元素
  • 然后将正序对第一个元素后面的元素都从小到大排列
    上面的过程就是找到一个正序对(i,j)
    说明从j开始往后,一直都是递减的,也就是说i后面的数字排列已经到达最大的字典许排列了,需要找到以一个比i大的数字来代替它。
    比如:
    8947521
    第一个正序对(4,7)
    这时候说明7521已经到达了最大的排列了。
    也可以说对于首位是4的数字来说,已经达到最大排列了
    这时候需要找到第一个比4大的数,而且只能从最后开始找,因为对于9这个数字来说,4开头还不是最大排列,至少要到7开头吧。
    这时候从右往左找到了5,交换4和5,说明4开头的已经排列完后要开始排列5了,那么现在是5开头,后面变成了7421,这时候还是能够保证从大到小的排列,然后需要将7421从小到达排列,即变成了8951247,这时候有继续上面的过程,找到正序对,交换,交换。比如(4,7),交换,交换就可以了。这样就可以将895开头的排列搞完了。
    给定一个序列,输出无重复,且按字典序的全排列——字典序算法_第1张图片
public class L24 {
     
	public ArrayList<String> Permutation(String str) {
     
	       ArrayList<String> res = new ArrayList<String>();
	       //字符串是空
	       if(str==null || str.length() == 0) return res;
	       //将字符串重排序
	       char[] aray = str.toCharArray();
	       Arrays.sort(aray);
	       String s = new String(aray);
	       
	       res.add(str);
	       while(true) {
     
	    	   s = nextString(s);
	    		   if(!s.equals("finish")){
     
	    		                   res.add(s);
	    		    }
	    		   else{
     
	                   break;
	                }    		   
	       }
	       return res;
    }
	public String nextString(String str) {
     
		char[] array = str.toCharArray();
		int lenght = str.length();
		int i = lenght-2;
		//从右往左找到第一个正序对
		for(;i>=0&&array[i]>=array[i+1];i--);
		if(i == -1) return "finish";
		//从右往左找到第一个比i大的
		int j = lenght-1;
		for(;j>=0&&array[j]<=array[i];j--);
		//交换i和j
		char tmp = array[i];
		array[i] = array[j];
		array[j] = tmp;
		//将i后面的重排列,使其从小到大排列,重复上面的过程
		for(int a = i+1,b=lenght-1;a<b;a++,b--) {
     
			tmp = array[a];
			array[a] = array[b];
			array[b] = tmp; 
		}
		return new String(array);
		
	}
}

你可能感兴趣的:(数据结构,算法,算法,字符串)