1. 程式人生 > >LeetCode-6. ZigZag Conversion(Z 字形變換)

LeetCode-6. ZigZag Conversion(Z 字形變換)

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

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

L   C   I   R
E T O E S I I G
E   D   H   N

之後,你的輸出需要從左往右逐行讀取,產生出一個新的字串,比如:"LCIRETOESIIGEDHN"

請你實現這個將字串進行指定行數變換的函式:

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
方法一:設定步長,上下掃描,分行收集

首先考慮字串長度小於行數和行數為1的情況,這兩種情況下,按Z字型排列分別為一豎行和一橫行,所以直接返回字串就可以了。

然後考慮一般情況,即字串排成Z字型的情況(這個排列是假想的,不需要真排出來)。從題目要求知,最終結果為每一行從上到下首尾相接。那就可以設定numRows

個字串陣列,然後按Z字形(其實就是按順序)遍歷字串,判斷每個字元所處的行數,把每一行都依次收集起來,最後把每一行的字串拼接起來。關鍵問題是行數是不斷在變化的,從頂端到底端,再從底端到頂端,不斷往復。這裡用步長(step)對行數進行控制,當位於第0行時,step=1,這樣從上往下每迴圈一次增加一行;當位於最底端時,step=-1,這樣從下往上每迴圈一次減少一行。

#Python3
class Solution:
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if len(s) <= numRows or numRows == 1:    #字串長度小於行數和行數為1的情況
            return s
        
        strs = [''] * numRows;step,row = 1,0    #設定numRows個字元陣列
        
        for char in s:    #按Z字形遍歷,其實就是順序遍歷
            strs[row] = strs[row] + char    #row行的字元全都加到row行
            if row == 0:    #處在頂端時,後面的遍歷必定從上往下
                step = 1
            elif row == numRows - 1:    #處在底端時,後面的遍歷必定從下往上
                step = -1
            row = row + step
        return ''.join(strs)    #把各行的字串組合到一起
//C++
class Solution {
public:
    string convert(string s, int numRows) {
        if(s.length() <= numRows || numRows == 1)
            return s;
        
        string strs[numRows];
        for(int i=0;i < numRows;i++){
            strs[i] = "";    //為每行設定一個空陣列
        }
        int step = 1,row = 0;
        
        for(int i = 0;i < s.length();i ++){
            strs[row] = strs[row] + s[i];
            if(row == 0) 
                step = 1;
            else if (row == numRows - 1) 
                step = -1;
            row = row + step;
        }
        string ans = "";
        for(int i = 0;i < numRows;i ++){    //把各行組合起來
            ans = ans + strs[i];
        }
        return ans;
    }
};