字符串的全排列

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串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("\n");
    }
}


*********************进入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;
    }
    
}

参考

大佬解答讨论

posted @ 2019-02-23 19:48  crr121  阅读(269)  评论(0编辑  收藏  举报