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

本系列導航:劍指offer(第二版)java實現(xiàn)導航帖](http://www.reibang.com/p/010410a4d419)

面試題38:字符串的排列

題目要求:
輸入一個字符串擅腰,打印出該字符串中字符的所有排列内舟。如輸入abc,則打印abc弄匕,acb,bac舶衬,bca暑脆,cab箱亿,cba。

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

對于a,b,c(下標為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(存入)

書中解法并未考慮有字符重復的問題劣纲。對于有重復字符的情況如a,a,b,交換0,1號元素前后是沒有變化的,即從生成的序列結果上看谁鳍,是同一種排列癞季,因此對于重復字符,不進行交換即可倘潜,思路如下:

對于a,a,b(下標為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相同,跳過

考慮了字符重復的解法的實現(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;
    }
    //下標為bound的字符依次與[bound,length)的字符交換涮因,如果相同不交換废睦,直到最后一個元素為止。
    //如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();
        }
    }
}

運行結果

abc
acb
bac
bca
cba
cab

aabb
abab
abba
baab
baba
bbaa
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末杖挣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子刚陡,更是在濱河造成了極大的恐慌惩妇,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筐乳,死亡現(xiàn)場離奇詭異歌殃,居然都是意外死亡,警方通過查閱死者的電腦和手機蝙云,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門氓皱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贮懈,你說我怎么就攤上這事匀泊。” “怎么了朵你?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵各聘,是天一觀的道長。 經(jīng)常有香客問我抡医,道長躲因,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任忌傻,我火速辦了婚禮大脉,結果婚禮上,老公的妹妹穿的比我還像新娘水孩。我一直安慰自己镰矿,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布俘种。 她就那樣靜靜地躺著秤标,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宙刘。 梳的紋絲不亂的頭發(fā)上苍姜,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音悬包,去河邊找鬼衙猪。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的垫释。 我是一名探鬼主播丝格,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼饶号!你這毒婦竟也來了铁追?” 一聲冷哼從身側響起季蚂,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤茫船,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扭屁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體算谈,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年料滥,在試婚紗的時候發(fā)現(xiàn)自己被綠了然眼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡葵腹,死狀恐怖高每,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情践宴,我是刑警寧澤鲸匿,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站阻肩,受9級特大地震影響带欢,放射性物質發(fā)生泄漏。R本人自食惡果不足惜烤惊,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一乔煞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柒室,春花似錦渡贾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至不脯,卻和暖如春府怯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背防楷。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工牺丙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓冲簿,卻偏偏與公主長得像粟判,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子峦剔,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容

  • 字符串的全排列 題目描述: 輸入一個字符串档礁,打印出該字符串中字符的所有排列。 例如輸入字符串a(chǎn)bc吝沫,則輸出由字符a...
    MinoyJet閱讀 11,243評論 4 11
  • 總結 想清楚再編碼 分析方法:舉例子呻澜、畫圖 第1節(jié):畫圖分析方法 對于二叉樹、二維數(shù)組惨险、鏈表等問題羹幸,都可以采用畫圖...
    M_巴拉巴拉閱讀 1,210評論 0 7
  • 劍指Offer筆試題(2) 題目來源:牛客網(wǎng) 題目一 復雜鏈表的復制 描述: 輸入一個復雜鏈表(每個節(jié)點中有節(jié)點...
    Torang閱讀 1,585評論 2 4
  • 1. Java基礎部分 基礎部分的順序:基本語法辫愉,類相關的語法栅受,內部類的語法,繼承相關的語法恭朗,異常的語法屏镊,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 本系列導航:劍指offer(第二版)java實現(xiàn)導航帖 面試題:字符串的組合 題目要求:輸入一個字符串,打印出該字...
    ryderchan閱讀 933評論 0 2