劍指offer第二版-38.字符串的排列

本系列導(dǎo)航:劍指offer(第二版)java實(shí)現(xiàn)導(dǎo)航帖](http://www.itdecent.cn/p/010410a4d419)

面試題38:字符串的排列

題目要求:
輸入一個(gè)字符串,打印出該字符串中字符的所有排列。如輸入abc,則打印abc,acb,bac,bca,cab,cba。

解題思路:
排列組合是數(shù)學(xué)上的常見問題。解題思路與數(shù)學(xué)上求排列總數(shù)類似:首先確定第一個(gè)位置的元素,然后依次確定每一個(gè)位置。以abc為例,我之前更習(xí)慣于設(shè)置三個(gè)空,然后選擇abc中的元素放入上述的空中。而書中給的思路是通過交換得到各種可能的排列,具體思路如下:

對于a,b,c(下標(biāo)為0,1,2)
0與0交換,得a,b,c => 1與1交換,得a,b,c =>2與2交換,得a,b,c(存入)
                => 1與2交換,得a,c,b =>2與2交換,得a,c.b(存入)
0與1交換,得b,a,c => 1與1交換,得b,a,c =>2與2交換,得b,a,c(存入)
                => 1與2交換,得b,c,a =>2與2交換,得b,c,a(存入)
0與2交換,得c,b,a => 1與1交換,得c,b,a =>2與2交換,得c,b,a(存入)
                => 1與2交換,得c,a,b =>2與2交換,得c,a.b(存入)

書中解法并未考慮有字符重復(fù)的問題。對于有重復(fù)字符的情況如a,a,b,交換0,1號元素前后是沒有變化的,即從生成的序列結(jié)果上看,是同一種排列,因此對于重復(fù)字符,不進(jìn)行交換即可,思路如下:

對于a,a,b(下標(biāo)為0,1,2)
0與0交換,得a,a,b => 1與1交換,得a,a,b =>2與2交換,得a,a,b(存入)
                => 1與2交換,得a,b,a =>2與2交換,得a,b,a(存入)
0與1相同,跳過
0與2交換,得b,a,a =>1與1交換,得b,a,a =>2與2交換,得b,a,a(存入)
                =>1與2相同,跳過

考慮了字符重復(fù)的解法的實(shí)現(xiàn)如下

package chapter4;

import java.util.*;

/**
 * Created by ryder on 2017/7/22.
 * 字符串的排列
 */
public class P197_StringPermutation {
    public static List<char[]> permutation(char[] strs) {
        if (strs == null || strs.length == 0)
            return null;
        List<char[]> ret = new LinkedList<>();
        permutationCore(strs, ret, 0);
        return ret;
    }
    //下標(biāo)為bound的字符依次與[bound,length)的字符交換,如果相同不交換,直到最后一個(gè)元素為止。
    //如a,b,c
    //0與0交換,得a,b,c => 1與1交換,得a,b,c =>2與2交換,得a,b,c(存入)
    //                => 1與2交換,得a,c,b =>2與2交換,得a,c.b(存入)
    //0與1交換,得b,a,c => 1與1交換,得b,a,c =>2與2交換,得b,a,c(存入)
    //                => 1與2交換,得b,c,a =>2與2交換,得b,c,a(存入)
    //0與2交換,得c,b,a => 1與1交換,得c,b,a =>2與2交換,得c,b,a(存入)
    //                => 1與2交換,得c,a,b =>2與2交換,得c,a.b(存入)

    //如a,a,b
    //0與0交換,得a,a,b => 1與1交換,得a,a,b =>2與2交換,得a,a,b(存入)
    //                => 1與2交換,得a,b,a =>2與2交換,得a,b,a(存入)
    //0與1相同,跳過
    //0與2交換,得b,a,a =>2與2交換,得b,a,a(存入)
    public static void permutationCore(char[] strs, List<char[]> ret, int bound) {
        if (bound == strs.length)
            ret.add(Arrays.copyOf(strs, strs.length));
        Set<Character> set = new HashSet<>();
        for (int i = bound; i < strs.length; i++) {
            if (set.add(strs[i])) {
                swap(strs, bound, i);
                permutationCore(strs, ret, bound + 1);
                swap(strs, bound, i);
            }
        }
    }

    public static void swap(char[] strs, int x, int y) {
        char temp = strs[x];
        strs[x] = strs[y];
        strs[y] = temp;
    }

    public static void main(String[] args) {
        char[] strs = {'a', 'b', 'c'};
        List<char[]> ret = permutation(strs);
        for (char[] item : ret) {
            for (int i = 0; i < item.length; i++)
                System.out.print(item[i]);
            System.out.println();
        }
        System.out.println();
        char[] strs2 = {'a', 'a', 'b','b'};
        List<char[]> ret2 = permutation(strs2);
        for (char[] item : ret2) {
            for (int i = 0; i < item.length; i++)
                System.out.print(item[i]);
            System.out.println();
        }
    }
}

運(yùn)行結(jié)果

abc
acb
bac
bca
cba
cab

aabb
abab
abba
baab
baba
bbaa
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 字符串的全排列 題目描述: 輸入一個(gè)字符串,打印出該字符串中字符的所有排列。 例如輸入字符串a(chǎn)bc,則輸出由字符a...
    MinoyJet閱讀 11,440評論 4 11
  • 總結(jié) 想清楚再編碼 分析方法:舉例子、畫圖 第1節(jié):畫圖分析方法 對于二叉樹、二維數(shù)組、鏈表等問題,都可以采用畫圖...
    M_巴拉巴拉閱讀 1,293評論 0 7
  • 劍指Offer筆試題(2) 題目來源:??途W(wǎng) 題目一 復(fù)雜鏈表的復(fù)制 描述: 輸入一個(gè)復(fù)雜鏈表(每個(gè)節(jié)點(diǎn)中有節(jié)點(diǎn)...
    Torang閱讀 1,634評論 2 4
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,638評論 18 399
  • 本系列導(dǎo)航:劍指offer(第二版)java實(shí)現(xiàn)導(dǎo)航帖 面試題:字符串的組合 題目要求:輸入一個(gè)字符串,打印出該字...
    ryderchan閱讀 988評論 0 2

友情鏈接更多精彩內(nèi)容