欣迪

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

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

And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string s, int numRows);

Example 1:

Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"

Example 2:

Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P     I    N
A   L S  I G
Y A   H R
P     I

Example 3:

Input: s = "A", numRows = 1
Output: "A"

Constraints:

  • 1 <= s.length <= 1000
  • s consists of English letters (lower-case and upper-case), ',' and '.'.
  • 1 <= numRows <= 1000

/**
 * @param {string} s
 * @param {number} numRows
 * @return {string}
 */
var convert = function(s, numRows) {
    if (numRows === 1) return s
    const keyPos = numRows * 2 - 2
    const arr = Array(numRows).fill('')
    let i = 0
    while (keyPos * i < s.length) {
        for (let j = 0; j < numRows; j++) {
            const key = keyPos * i + j
            if (s[key]) {
                arr[j] += s[key] 
            }
        }
        for (let k = 1; k < numRows - 1; k++) {
            const key = keyPos * i + (numRows - 1  + k)
            if (s[key]) {
                 arr[numRows - 1  - k] += s[key]
            }
        }
        i++
    }
    return arr.join('')
};

這題其實蠻燒腦的。

我的解法是直接放一個 size 等於 numRows 的陣列,每個陣列裡面放空字串。

接下來,偵測如果 numRows 是 1 則可以直接回傳 s 不用計算。

這邊可以計算出每 numRows * 2 – 2 會是一個新的循環,所以在最外的 while loop 不斷地增加循環數量直到超過字串的長度。

接下來則是把每個 loop 的開頭 numRows 個數字,依序填入 arr[0] ~ arr[numRows – 1]。

後面則是繼續填入鋸齒形狀的斜坡。

全部完成後,再把每一個再把陣列的內容 join 起來。

訂閱 IT-Monk

訂閱最新文章的發布消息! 😚😚😚
Loading

作者介紹 - 欣迪

欣迪

從設計到寫程式,發現自己有追求前端技巧的自虐傾向。不斷的踩坑,再從坑裡爬出來,慢慢對攀岩有點心得。 目前在多間公司擔任網站設計顧問。 同時也是網站架設公司負責人。