1. 程式人生 > 其它 >【LeetCode】Z 字形變換(JS實現)

【LeetCode】Z 字形變換(JS實現)

技術標籤:leetcodejavascriptes6

問題

今天開始在leetcode刷演算法題,遇到這樣一道題,題目看上去就有點好玩,就進去試了一下:

將一個給定字串 s 根據給定的行數 numRows ,以從上往下、從左到右進行Z 字形排列。

比如輸入字串為 "PAYPALISHIRING"行數為 3 時,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

輸出結果就是"PAHNAPLSIIGYIR“

思路

最開始,對這樣的題目有一絲絲摸不到頭腦,於是希望可以從這個z字形排列出的結果中找到一些規律。

既然要找規律,我假定一個字串:HELLOGEPINGLI

行號
1HEI
2EGPL
3LOIG
4LN

那結果如上面所示,應該是HEI(第一行對應的字串)+EGPL(第二行對應的字串)+LOIG(第三行對應的字串)+LN(第四行對應的字串)

於是現在我們有了第一個想法,我們弄一個數組,ROWS,有幾行,這個陣列就有幾項。

下面,我們就需要研究下一個問題點了,我們如何去確定每一行對應的字串是什麼,所以,還是要找一找規律。

首先,我們一看就可以輕鬆的發現,4行的情況下,是每6個字元一個迴圈。如下圖所示,迴圈週期是2*numRows-2。

為什麼是2*numRows-2呢,也很容易。看下面的圖可以明白,兩倍的行數,再去掉頭尾兩個。

下面,我們繼續以之前四行的例子繼續看 字元會出現在哪一行的規律。

rows
0

position=0

0%6=0

6-0=6

position=6
1

position=1

1%6=1

6-1=5

position=5

5%6=5

6-5=1

position=7
2

position=2

2%6=2

6-2=4

position=4

4%6=4

6-4=2

position=8
3

position=3

3%6=3

6-3=3

position=9

上圖,position代表的是字元在原字串中的位置,6是2*numRows-2的計算結果(2*4-2=6)。我們不難的發現,行數其實是position%(2*numRows-2)和(2*numRows-2)-position%(2*numRows-2)的最小值。

那麼這樣問題就可以很順利的解決了。

程式碼

var convert = function(s, numRows) {
    if (numRows === 1) return s;
    const rows = new Array(numRows).fill("");
    const period = 2 * numRows - 2;
    for(let i = 0; i < s.length; i++) {
        rows[Math.min(i % period, period - i % period)] += s[i];
    }
    return rows.join("");
};