2024.09.22 力扣刷題 Z字形變換

夏天喝啤酒發表於2024-09-22

題目:

將一個給定字串 s 根據給定的行數 numRows ,以從上往下、從左到右進行 Z 字形排列。
比如輸入字串為 "PAYPALISHIRING" 行數為 3 時,排列如下:
P A H N
A P L S I I G
Y I R
之後,你的輸出需要從左往右逐行讀取,產生出一個新的字串,比如:"PAHNAPLSIIGYIR"。
請你實現這個將字串進行指定行數變換的函式:
string convert(string s, int numRows);

示例 1:
輸入:s = "PAYPALISHIRING", numRows = 3
輸出:"PAHNAPLSIIGYIR"

示例 2:
輸入:s = "PAYPALISHIRING", numRows = 4
輸出:"PINALSIGYAHRPI"
解釋:
P I N
A L S I G
Y A H R
P I

示例 3:
輸入:s = "A", numRows = 1
輸出:"A"

上面就是題目的內容,難度標註的是中等,拿到題目讀了有一會兒,剛開始不是很懂,後面看了示例大概明白了一些。
我當時的第一反應是進行字串抽點,Z形應該是有規律可以找的,我設定了row = 3,4,5分別進行了規律查詢:
當row = 3時,輸入“PAYPALISHIRING”,透過觀察Z形,可以看到下標0的P到A時需要有3個字元間隔,下標為1的A到P有1個字元間隔,到Y到I的字元間隔和第1個P到A的字元間隔一致。

但是需要注意的是,當row = 4或5時,其字元間隔會發生變化且數值有兩種可能。如下所示(row = 4):

A到L的字元間隔數和L到S的字元間隔數會發生變化,且只有兩種情況。

按此推論,從row = 3,4,5的情況下的字元排布,得出各行到下一個字元的間隔數遵循下述規律:
nums=2*(row-1-index)-1;
nums是字元間隔數,row是輸入的行數,index是要拼接的每行的下標(若row=6,那麼index=[0,5])
當row=4:
index=0,nums=5
index=1,nums=3
index=2,nums=1
index=3,nums=5(同index=0的情況)
也就是說index=0的P到I,中間需要跨5個字元,index=1的A到L需要跨3個字元,但是L到S需要跨1個字元,所以當row為偶數時,需要前後對稱構成一組進行遍歷,當row為奇數時,中間的index只需要按自己的nums進行遍歷。

我提交的程式碼如下:

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1)
            return s;
        int* index = new int[numRows]{};
        for (int i = 0; i < (numRows % 2 == 0 ? numRows / 2 : numRows / 2 + 1); ++i) {
            if (i == (numRows - 1 - i)) {
                index[i] = 2 * (numRows - 1 - i) - 1;
            }
            else {
                index[i]= 2 * (numRows - 1 - i) - 1;
                index[numRows -1-i]= i == 0 ? index[i] : 2 * (numRows - 1 - (numRows - 1 - i)) - 1;
            }
        }

        int now_index = 0;
        std::string output;
        for (int i = 0; i < numRows; ++i) {
            now_index = i;
            std::string temp;
            bool flag = true;
            int a = index[i] + 1;
            int b = index[numRows - 1 - i] + 1;
            while (now_index < s.length()) {
                temp += s[now_index];
                now_index += flag ? a : b;
                flag = !flag;
            }
            output += temp;
        }
        delete[] index;

        return output;
    }
};

結果如下:

相關文章