LeetCode(6) ---- ZigZag Conversion

1.問題

question.png

2.題目意思

給定一個字符串晶密,使它按照Z字型排列(說起來應(yīng)該是一個倒N字形吧)财松,這個Z字形的大小由傳入的參數(shù)決定,然后我們應(yīng)該返回一個順序讀的字符串

3.思路

當時找了個紙畫了一下扩然,不過等想起寫博客的時候紙已經(jīng)不見了……
為了 彌補我的過失觅闽,特地畫了一個狗血的示意圖帝雇。【processon.com】


image.png

按照圖中所示蛉拙,我們目前拿數(shù)組下標來表示數(shù)據(jù)尸闸,而且整個題目都會以數(shù)組下標作為關(guān)鍵。那我們的核心就是創(chuàng)建一個StringBuilder孕锄,直接從源字符串取數(shù)據(jù)進行append吮廉,像是一種沒有進行zigzag排序,直接進行合理的字符串選取.

  • 圖中可以顯然知道numRows等于4畸肆,也就是說在字符串長度內(nèi)宦芦,首先訪問第一排數(shù)字 0,6轴脐,12 (這里我把轉(zhuǎn)折點理解做兩個重疊的數(shù))调卑,參考下面的代碼,i = 0時豁辉,在字符串長度范圍內(nèi)令野,添加第一個字符舀患,
  • 下一行代碼 j += 2*(numRows-i-1);是一個找規(guī)律找出來的數(shù)學公式徽级,有種像初中找規(guī)律的題,就是說我們要確定3這個轉(zhuǎn)折點到6這個轉(zhuǎn)折點中間有多少數(shù)據(jù)聊浅,當然我們口算都能答上來的問題餐抢,計算機可需要提示现使,那么我們看到下面的圖的數(shù)據(jù)


    image.png
numRows = 4
0  --- 6  間隔6  (i = 0)
1 --- 5   間隔4  (i =  1)
2 --- 4   間隔2  (i =  2)
3 --- 3   間隔0  (i =  3)

那么我們把他轉(zhuǎn)換成一個找規(guī)律的數(shù)學題,小學生也可以找到規(guī)律吧旷痕,
6碳锈,4,2欺抗,0 也就是 2(4-i-1) 或者 2(numRows-i-1); 可以帶入值驗證一下售碳。

  • 當然我們這個是不夠的,因為這是一個V的形狀绞呈, 倒V的形狀是一個反的公式贸人,2*i ,大家可以研究一下佃声。


    image.png
  • 那么這個循環(huán)就可以理解了艺智,訪問添加第一個字符,按照V型公式位移j圾亏,判斷位移后的j的合法性十拣,而且需要判斷是否是轉(zhuǎn)折點(因為我們剛才說假設(shè)轉(zhuǎn)折點兩個重復數(shù)據(jù)的情況,這里只需要添加一個才能滿足題意)志鹃,合法后添加字符串夭问,接著按照倒V型公式位移j,直到字符串遍歷完成曹铃。

 while(j < s.length()){
               sb.append(s.charAt(j));
               j += 2*(numRows-i-1);
               if(i!=numRows-1&&i!=0&&j<=s.length()-1)
               {
                  sb.append(s.charAt(j));   
               }
               j += 2*i;
           }
  • 最后的i循環(huán)甲喝,就是控制一層一層向下遍歷。此外一些特殊的情況铛只,numRows == 1的情況埠胖,直接返回,采用StringBuilder方式加快構(gòu)造字符串

4.代碼

class Solution {
    public String convert(String s, int numRows) {
       int j = 0;
        if(numRows == 1){
           return s;
       }
       StringBuilder sb = new StringBuilder();
       for(int i=0;i<numRows;i++){
           j = i;
           while(j < s.length()){
               sb.append(s.charAt(j));
               j += 2*(numRows-i-1);
               if(i!=numRows-1&&i!=0&&j<=s.length()-1)
               {
                  sb.append(s.charAt(j));   
               }
               j += 2*i;
           }
       }
       return sb.toString();
    }
}

5.大佬算法

public String convert(String s, int nRows) {
    char[] c = s.toCharArray();
    int len = c.length;
    StringBuffer[] sb = new StringBuffer[nRows];
    for (int i = 0; i < sb.length; i++) sb[i] = new StringBuffer();
    
    int i = 0;
    while (i < len) {
        for (int idx = 0; idx < nRows && i < len; idx++) // vertically down
            sb[idx].append(c[i++]);
        for (int idx = nRows-2; idx >= 1 && i < len; idx--) // obliquely up
            sb[idx].append(c[i++]);
    }
    for (int idx = 1; idx < sb.length; idx++)
        sb[0].append(sb[idx]);
    return sb[0].toString();
}

這個算法淳玩,也算是空間換取時間吧直撤,建立一個StringBuffer數(shù)組,數(shù)組長度是nRows的長度蜕着,首先初始化谋竖,接著來一遍字符串循環(huán),然后把豎行數(shù)據(jù)分別添加到StringBuffer[0] ,StringBuffer[1],StringBuffer[2] ……StringBuffer[nRows -1]承匣,然后下一個循環(huán)是把斜行數(shù)據(jù)存起來蓖乘,如此循環(huán),那么我們就可以知道韧骗,StringBuffer[n] 存的就是第n橫行的數(shù)據(jù)嘉抒,這樣子在最后的循環(huán)中拼接到StringBuffer[0]上就行了。

6.根據(jù)大佬算法改進我的算法

class Solution {
    public String convert(String s, int numRows) {
          int i,j = 0;
        if(numRows == 1){
            return s;
        }
        StringBuffer[] sbs = new StringBuffer[numRows];
        for ( i = 0; i < sbs.length; i++) sbs[i] = new StringBuffer();

        i = 0;
        while(j < s.length() && i < numRows){

            sbs[i].append(s.charAt(j));
            j += 2*(numRows-i-1);
            if(i!=numRows-1&&i!=0&&j<=s.length()-1)
            {
                sbs[i].append(s.charAt(j));
            }
            j += 2*i;
            if(s.length() <= j ){
                j = ++i;
            }

        }

        for (i = 1; i < sbs.length; i++)
            sbs[0].append(sbs[i]);

        return sbs[0].toString();
    }
}

這樣優(yōu)化的話袍暴,從240ms的用時到了50多些侍,核心的思想隶症,也就是那個公式?jīng)]有變,增加了StringBuffer來數(shù)組來管理數(shù)據(jù)岗宣。

7.總結(jié)

人丑就得多讀書蚂会。

LeeCode 之旅繼續(xù).

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市耗式,隨后出現(xiàn)的幾起案子胁住,更是在濱河造成了極大的恐慌,老刑警劉巖刊咳,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件措嵌,死亡現(xiàn)場離奇詭異,居然都是意外死亡芦缰,警方通過查閱死者的電腦和手機企巢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來让蕾,“玉大人浪规,你說我怎么就攤上這事√叫ⅲ” “怎么了笋婿?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長顿颅。 經(jīng)常有香客問我缸濒,道長,這世上最難降的妖魔是什么粱腻? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任庇配,我火速辦了婚禮,結(jié)果婚禮上绍些,老公的妹妹穿的比我還像新娘捞慌。我一直安慰自己,他們只是感情好柬批,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布啸澡。 她就那樣靜靜地躺著,像睡著了一般氮帐。 火紅的嫁衣襯著肌膚如雪嗅虏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天上沐,我揣著相機與錄音皮服,去河邊找鬼。 笑死,一個胖子當著我的面吹牛冰更,可吹牛的內(nèi)容都是我干的产徊。 我是一名探鬼主播昂勒,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蜀细,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了戈盈?” 一聲冷哼從身側(cè)響起奠衔,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎塘娶,沒想到半個月后归斤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡刁岸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年脏里,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虹曙。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡迫横,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酝碳,到底是詐尸還是另有隱情矾踱,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布疏哗,位于F島的核電站呛讲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏返奉。R本人自食惡果不足惜贝搁,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芽偏。 院中可真熱鬧徘公,春花似錦、人聲如沸哮针。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽十厢。三九已至等太,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛮放,已是汗流浹背缩抡。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留包颁,地道東北人瞻想。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓压真,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蘑险。 傳聞我的和親對象是個殘疾皇子滴肿,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗。 張土汪:刷leetcod...
    土汪閱讀 12,744評論 0 33
  • 計算機二級C語言上機題庫(南開版) 1.m個人的成績存放在score數(shù)組中佃迄,請編寫函數(shù)fun,它的功能是:將低于平...
    MrSunbeam閱讀 6,366評論 1 42
  • LeetCode -- 6. ZigZag Conversion 題目描述 The string "PAYPALI...
    sea_baby閱讀 468評論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法泼差,類相關(guān)的語法,內(nèi)部類的語法呵俏,繼承相關(guān)的語法堆缘,異常的語法,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 今天第四節(jié)課普碎,老師怪模怪樣的進了教室吼肥,手里還拿了一個大大的東西,我們仔細一看原來是一個鼓麻车,老師打鼓干啥呀這節(jié)課就不...
    王昱凱閱讀 223評論 0 0