按字典序打印出该字符串中字符的所有排列

按字典序打印出该字符串中字符的所有排列

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。


这道题的关键是字典序算法。字典序算法就是用来求全排列的,具体的证明过程我也没有看,但是步骤是能理解的,就是不断构造逆序

img


import java.util.*;
public class Solution {
    public ArrayList<String> Permutation(String str) {
        //结果集合
        ArrayList<String> res = new ArrayList<String>();
        //特殊情况处理
        if(str.length() == 0) return res;
        //将String转换为字符数组
        char [] array = str.toCharArray();
        //对字符数组sort
        Arrays.sort(array);
        //由sort后的数组构建字符串
        String s = new String(array);
        //这种字典序的就是一种情况
        res.add(str);
        while(true){
            s = nextString(s);
            //nextString以finish作为结束符号,当然再加个标点就更好了,避免和结果重复
            if(!s.equals("finish")){
                res.add(s);
            }
            else{
                break;
            }
        }
        return res;
    }
 
    public String nextString(String str){
        //再换回字符数组
        char [] array = str.toCharArray();
        //数组长度
        int length = str.length();
        //从倒数第二个开始
        int i = length-2;
        //一直到array[i] < array[i+1]
        for(; i>=0 && array[i] >= array[i+1]; i--);
        //如果没有正序的了,就结束
        if(i == -1) return "finish";
        //j指向末尾
        int j = length-1;
        //j一直找到第一个比array[i]大的j的位置
        for(; j>=0 && array[j] <= array[i]; j--);
        //swap i,j
        char tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
        Arrays.sort(array,i+1,length);
        return new String(array);
    }
}

这个算法证明有些繁琐,不用去理会。但是算法是很重要的,需要掌握


  1. Array对象,例如数组int[],获取长度用的是length字段,而字符串用的是length()方法,太容易混了
  2. 注意一个错误:i=i++,这种写法是错误的,因为++在右面,是先赋值再加,所以相当于没有加上,应该直接i++
  3. 对基本类型的数组进行排序:Arrays.sort([] array,int from,int to);注意排序区间依然是左闭右开的
posted @ 2020-03-05 18:06  别再闹了  阅读(354)  评论(0)    收藏  举报