剑指Offer对答如流系列

面试题38:字符串的排列

题目描述

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

问题分析

把字符串分为两部分:一部分是第一个字符,另一部分是后面的所有字符。

首先,我们要确定第一个字符,该字符可以是字符串中的任意一个;其次固定第一个字符后,求出后面所有字符的排列。

实现第一个字符的改变,仅需将第一个字符和后面所有字符进行交换即可。

要记得字符串输出后要将字符变回原始的字符串。只有这样 ABC字符串才能够出现Swap A with A/B/C 的情况,如果Swap A with B之后不变回原始的字符串,我们后面的操作就基于BAC了,Swap A with A/C就不容易实现了。从下图可以看出
在这里插入图片描述

完整的交换图示如下:

在这里插入图片描述

问题解答

  public ArrayList<String> Permutation(String str) {
        ArrayList<String> list = new ArrayList<>();
        if(str==null || str.length()==0) {
            return list;
        }
        permutationCore(str.toCharArray(),0,list);
        Collections.sort(list);  //将list中的字符串排序
        return list;
    }

    private void permutationCore(char[] strArray,int index,ArrayList<String> list){
        if(index==strArray.length-1){
            //判断是否有重复字符串
            if(!list.contains(String.valueOf(strArray))) {
                list.add(String.valueOf(strArray));
            }
        } else {
            for(int i=index;i<strArray.length;i++){
                // 交换
                char temp=strArray[index];
                strArray[index]=strArray[i];
                strArray[i]=temp;
                permutationCore(strArray,index+1,list);
                // 重置回来
                strArray[i]=strArray[index];
                strArray[index]=temp;
            }
        }
    }
原文地址:https://www.cnblogs.com/JefferyChenXiao/p/12246432.html