• 字符串的全排列


    题目描述

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

    输入描述:

    输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
    

    分析思路一

    image

    分析思路二

    image

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class Solution {
           static  int  count = 0;
    
        public static void main(String[] args) {
            Solution p = new Solution();
            System.out.println(p.Permutation("abcd").toString());
        }
    
        public ArrayList<String> Permutation(String str) {
            System.out.println("*********************进入Permutation方法*****************");
    
            List<String> res = new ArrayList<>();
            if (str != null && str.length() > 0) {
    
                PermutationHelper(str.toCharArray(), 0, res);
                Collections.sort(res);
            }
            return (ArrayList)res;
        }
    
        /**
         *
         * @param cs 输入的字符串数组
         * @param i 要替换的字符的下标
         * @param list 全排列
         */
        public void PermutationHelper(char[] cs, int i, List<String> list) {
            count++;
            System.out.println("*********************第"+count+"次进入PermutationHelper方法*****************");
            System.out.print("当前数组顺序:");
            printCs(cs);
            if (i == cs.length - 1) {
                System.out.println("i == cs.length - 1");
                System.out.println("将cs数组加入list");
                String val = String.valueOf(cs);
                if (!list.contains(val))
                    list.add(val);
                System.out.println("list=》"+list.toString());
            } else {
                System.out.println("i="+i);
                System.out.println("for循环 for (int j = i; j < cs.length; j++)");
                for (int j = i; j < cs.length; j++) {
                    System.out.println("i="+i + "&&"+"j="+j);
                    System.out.println("位置i=>"+i+"和位置j=>"+j+"交换");
                    swap(cs, i, j);
                    System.out.println("=====交换后的数组第一次=====");
                    printCs(cs);
                    System.out.println("i="+i+"&&"+"i+1="+(i+1));
                    System.out.println("递归进入:");
                    PermutationHelper(cs, i+1, list);
                    swap(cs, i, j);
                    System.out.println("=====交换后的数组第二次=====");
                    printCs(cs);
                }
            }
        }
    
        public void swap(char[] cs, int i, int j) {
    
            char temp = cs[i];
            cs[i] = cs[j];
            cs[j] = temp;
        }
        public void printCs(char[] cs){
    
            for(int i = 0; i < cs.length; i++){
                System.out.print(cs[i]);
            }
            System.out.println("
    ");
        }
    }
    
    
    
    *********************进入Permutation方法*****************
    *********************1次进入PermutationHelper方法*****************
    当前数组顺序:abcd
    
    i=0
    for循环 for (int j = i; j < cs.length; j++)
    i=0&&j=0
    位置i=>0和位置j=>0交换
    =====交换后的数组第一次=====
    abcd
    
    i=0&&i+1=>1
    递归进入:
    *********************2次进入PermutationHelper方法*****************
    当前数组顺序:abcd
    
    i=1
    for循环 for (int j = i; j < cs.length; j++)
    i=1&&j=1
    位置i=>1和位置j=>1交换
    =====交换后的数组第一次=====
    abcd
    
    i=1&&i+1=>2
    递归进入:
    *********************3次进入PermutationHelper方法*****************
    当前数组顺序:abcd
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    abcd
    
    i=2&&i+1=>3
    递归进入:
    *********************4次进入PermutationHelper方法*****************
    当前数组顺序:abcd
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd]
    =====交换后的数组第二次=====
    abcd
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    abdc
    
    i=2&&i+1=>3
    递归进入:
    *********************5次进入PermutationHelper方法*****************
    当前数组顺序:abdc
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc]
    =====交换后的数组第二次=====
    abcd
    
    =====交换后的数组第二次=====
    abcd
    
    i=1&&j=2
    位置i=>1和位置j=>2交换
    =====交换后的数组第一次=====
    acbd
    
    i=1&&i+1=>2
    递归进入:
    *********************6次进入PermutationHelper方法*****************
    当前数组顺序:acbd
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    acbd
    
    i=2&&i+1=>3
    递归进入:
    *********************7次进入PermutationHelper方法*****************
    当前数组顺序:acbd
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd]
    =====交换后的数组第二次=====
    acbd
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    acdb
    
    i=2&&i+1=>3
    递归进入:
    *********************8次进入PermutationHelper方法*****************
    当前数组顺序:acdb
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb]
    =====交换后的数组第二次=====
    acbd
    
    =====交换后的数组第二次=====
    abcd
    
    i=1&&j=3
    位置i=>1和位置j=>3交换
    =====交换后的数组第一次=====
    adcb
    
    i=1&&i+1=>2
    递归进入:
    *********************9次进入PermutationHelper方法*****************
    当前数组顺序:adcb
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    adcb
    
    i=2&&i+1=>3
    递归进入:
    *********************10次进入PermutationHelper方法*****************
    当前数组顺序:adcb
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb]
    =====交换后的数组第二次=====
    adcb
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    adbc
    
    i=2&&i+1=>3
    递归进入:
    *********************11次进入PermutationHelper方法*****************
    当前数组顺序:adbc
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc]
    =====交换后的数组第二次=====
    adcb
    
    =====交换后的数组第二次=====
    abcd
    
    =====交换后的数组第二次=====
    abcd
    
    i=0&&j=1
    位置i=>0和位置j=>1交换
    =====交换后的数组第一次=====
    bacd
    
    i=0&&i+1=>1
    递归进入:
    *********************12次进入PermutationHelper方法*****************
    当前数组顺序:bacd
    
    i=1
    for循环 for (int j = i; j < cs.length; j++)
    i=1&&j=1
    位置i=>1和位置j=>1交换
    =====交换后的数组第一次=====
    bacd
    
    i=1&&i+1=>2
    递归进入:
    *********************13次进入PermutationHelper方法*****************
    当前数组顺序:bacd
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    bacd
    
    i=2&&i+1=>3
    递归进入:
    *********************14次进入PermutationHelper方法*****************
    当前数组顺序:bacd
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd]
    =====交换后的数组第二次=====
    bacd
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    badc
    
    i=2&&i+1=>3
    递归进入:
    *********************15次进入PermutationHelper方法*****************
    当前数组顺序:badc
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc]
    =====交换后的数组第二次=====
    bacd
    
    =====交换后的数组第二次=====
    bacd
    
    i=1&&j=2
    位置i=>1和位置j=>2交换
    =====交换后的数组第一次=====
    bcad
    
    i=1&&i+1=>2
    递归进入:
    *********************16次进入PermutationHelper方法*****************
    当前数组顺序:bcad
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    bcad
    
    i=2&&i+1=>3
    递归进入:
    *********************17次进入PermutationHelper方法*****************
    当前数组顺序:bcad
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad]
    =====交换后的数组第二次=====
    bcad
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    bcda
    
    i=2&&i+1=>3
    递归进入:
    *********************18次进入PermutationHelper方法*****************
    当前数组顺序:bcda
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda]
    =====交换后的数组第二次=====
    bcad
    
    =====交换后的数组第二次=====
    bacd
    
    i=1&&j=3
    位置i=>1和位置j=>3交换
    =====交换后的数组第一次=====
    bdca
    
    i=1&&i+1=>2
    递归进入:
    *********************19次进入PermutationHelper方法*****************
    当前数组顺序:bdca
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    bdca
    
    i=2&&i+1=>3
    递归进入:
    *********************20次进入PermutationHelper方法*****************
    当前数组顺序:bdca
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca]
    =====交换后的数组第二次=====
    bdca
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    bdac
    
    i=2&&i+1=>3
    递归进入:
    *********************21次进入PermutationHelper方法*****************
    当前数组顺序:bdac
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac]
    =====交换后的数组第二次=====
    bdca
    
    =====交换后的数组第二次=====
    bacd
    
    =====交换后的数组第二次=====
    abcd
    
    i=0&&j=2
    位置i=>0和位置j=>2交换
    =====交换后的数组第一次=====
    cbad
    
    i=0&&i+1=>1
    递归进入:
    *********************22次进入PermutationHelper方法*****************
    当前数组顺序:cbad
    
    i=1
    for循环 for (int j = i; j < cs.length; j++)
    i=1&&j=1
    位置i=>1和位置j=>1交换
    =====交换后的数组第一次=====
    cbad
    
    i=1&&i+1=>2
    递归进入:
    *********************23次进入PermutationHelper方法*****************
    当前数组顺序:cbad
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    cbad
    
    i=2&&i+1=>3
    递归进入:
    *********************24次进入PermutationHelper方法*****************
    当前数组顺序:cbad
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad]
    =====交换后的数组第二次=====
    cbad
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    cbda
    
    i=2&&i+1=>3
    递归进入:
    *********************25次进入PermutationHelper方法*****************
    当前数组顺序:cbda
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda]
    =====交换后的数组第二次=====
    cbad
    
    =====交换后的数组第二次=====
    cbad
    
    i=1&&j=2
    位置i=>1和位置j=>2交换
    =====交换后的数组第一次=====
    cabd
    
    i=1&&i+1=>2
    递归进入:
    *********************26次进入PermutationHelper方法*****************
    当前数组顺序:cabd
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    cabd
    
    i=2&&i+1=>3
    递归进入:
    *********************27次进入PermutationHelper方法*****************
    当前数组顺序:cabd
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd]
    =====交换后的数组第二次=====
    cabd
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    cadb
    
    i=2&&i+1=>3
    递归进入:
    *********************28次进入PermutationHelper方法*****************
    当前数组顺序:cadb
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb]
    =====交换后的数组第二次=====
    cabd
    
    =====交换后的数组第二次=====
    cbad
    
    i=1&&j=3
    位置i=>1和位置j=>3交换
    =====交换后的数组第一次=====
    cdab
    
    i=1&&i+1=>2
    递归进入:
    *********************29次进入PermutationHelper方法*****************
    当前数组顺序:cdab
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    cdab
    
    i=2&&i+1=>3
    递归进入:
    *********************30次进入PermutationHelper方法*****************
    当前数组顺序:cdab
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab]
    =====交换后的数组第二次=====
    cdab
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    cdba
    
    i=2&&i+1=>3
    递归进入:
    *********************31次进入PermutationHelper方法*****************
    当前数组顺序:cdba
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab, cdba]
    =====交换后的数组第二次=====
    cdab
    
    =====交换后的数组第二次=====
    cbad
    
    =====交换后的数组第二次=====
    abcd
    
    i=0&&j=3
    位置i=>0和位置j=>3交换
    =====交换后的数组第一次=====
    dbca
    
    i=0&&i+1=>1
    递归进入:
    *********************32次进入PermutationHelper方法*****************
    当前数组顺序:dbca
    
    i=1
    for循环 for (int j = i; j < cs.length; j++)
    i=1&&j=1
    位置i=>1和位置j=>1交换
    =====交换后的数组第一次=====
    dbca
    
    i=1&&i+1=>2
    递归进入:
    *********************33次进入PermutationHelper方法*****************
    当前数组顺序:dbca
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    dbca
    
    i=2&&i+1=>3
    递归进入:
    *********************34次进入PermutationHelper方法*****************
    当前数组顺序:dbca
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab, cdba, dbca]
    =====交换后的数组第二次=====
    dbca
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    dbac
    
    i=2&&i+1=>3
    递归进入:
    *********************35次进入PermutationHelper方法*****************
    当前数组顺序:dbac
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab, cdba, dbca, dbac]
    =====交换后的数组第二次=====
    dbca
    
    =====交换后的数组第二次=====
    dbca
    
    i=1&&j=2
    位置i=>1和位置j=>2交换
    =====交换后的数组第一次=====
    dcba
    
    i=1&&i+1=>2
    递归进入:
    *********************36次进入PermutationHelper方法*****************
    当前数组顺序:dcba
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    dcba
    
    i=2&&i+1=>3
    递归进入:
    *********************37次进入PermutationHelper方法*****************
    当前数组顺序:dcba
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab, cdba, dbca, dbac, dcba]
    =====交换后的数组第二次=====
    dcba
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    dcab
    
    i=2&&i+1=>3
    递归进入:
    *********************38次进入PermutationHelper方法*****************
    当前数组顺序:dcab
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab, cdba, dbca, dbac, dcba, dcab]
    =====交换后的数组第二次=====
    dcba
    
    =====交换后的数组第二次=====
    dbca
    
    i=1&&j=3
    位置i=>1和位置j=>3交换
    =====交换后的数组第一次=====
    dacb
    
    i=1&&i+1=>2
    递归进入:
    *********************39次进入PermutationHelper方法*****************
    当前数组顺序:dacb
    
    i=2
    for循环 for (int j = i; j < cs.length; j++)
    i=2&&j=2
    位置i=>2和位置j=>2交换
    =====交换后的数组第一次=====
    dacb
    
    i=2&&i+1=>3
    递归进入:
    *********************40次进入PermutationHelper方法*****************
    当前数组顺序:dacb
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab, cdba, dbca, dbac, dcba, dcab, dacb]
    =====交换后的数组第二次=====
    dacb
    
    i=2&&j=3
    位置i=>2和位置j=>3交换
    =====交换后的数组第一次=====
    dabc
    
    i=2&&i+1=>3
    递归进入:
    *********************41次进入PermutationHelper方法*****************
    当前数组顺序:dabc
    
    i == cs.length - 1
    将cs数组加入list
    list=[abcd, abdc, acbd, acdb, adcb, adbc, bacd, badc, bcad, bcda, bdca, bdac, cbad, cbda, cabd, cadb, cdab, cdba, dbca, dbac, dcba, dcab, dacb, dabc]
    =====交换后的数组第二次=====
    dacb
    
    =====交换后的数组第二次=====
    dbca
    
    =====交换后的数组第二次=====
    abcd
    
    [abcd, abdc, acbd, acdb, adbc, adcb, bacd, badc, bcad, bcda, bdac, bdca, cabd, cadb, cbad, cbda, cdab, cdba, dabc, dacb, dbac, dbca, dcab, dcba]
    
    Process finished with exit code 0
    
    
    [abcd, abdc, acbd, acdb, adbc, adcb, bacd, badc, bcad, bcda, bdac, bdca, cabd, cadb, cbad, cbda, cdab, cdba, dabc, dacb, dbac, dbca, dcab, dcba]
    

    通过观察该列表的顺序可知,该递归的方式相当于后序遍历,但是为什么没有出现根节点呢,因为

     if (!list.contains(val))
                    list.add(val);
    

    进行了去重

    简洁代码

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    public class Solution {
        public ArrayList<String> Permutation(String str) {
             List<String> res = new ArrayList<>();
            if (str != null && str.length() > 0) {
                PermutationHelper(str.toCharArray(), 0, res);
                Collections.sort(res);
            }
            return (ArrayList)res;
        }
        
         public void PermutationHelper(char[] cs, int i, List<String> list) {
    
            if (i == cs.length - 1) {          
                String val = String.valueOf(cs);
                if (!list.contains(val))
                    list.add(val);        
            } else {
              
                for (int j = i; j < cs.length; j++) {          
                    swap(cs, i, j);
                    PermutationHelper(cs, i+1, list);
                    swap(cs, i, j);
                }
            }
        }
    
        public void swap(char[] cs, int i, int j) {
            char temp = cs[i];
            cs[i] = cs[j];
            cs[j] = temp;
        }
        
    }
    

    参考

    大佬解答讨论

  • 相关阅读:
    JAVA中线程池启动定时任务
    JAVA线程池的创建
    JAVA多线程售票问题
    设计模式之一 ---单例模式
    JAVAWeb使用POI做导出Excel
    ThreadLocal实现线程范围内共享
    线程的互斥与同步通信
    Spring-task-timer定时器
    万年历---java版
    linux sed 批量替换字符串
  • 原文地址:https://www.cnblogs.com/flyingcr/p/10428281.html
Copyright © 2020-2023  润新知