1. 程式人生 > 其它 >每日一練——Z 字形變換(python)

每日一練——Z 字形變換(python)

技術標籤:每日一練python學習

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

比如輸入字串為 “LEETCODEISHIRING” 行數為 3 時,排列如下:
在這裡插入圖片描述
之後,你的輸出需要從左往右逐行讀取,產生出一個新的字串,比如:“LCIRETOESIIGEDHN”。

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

思路1:
看到題目的第一時間,想到要使用二維陣列來儲存最終排列的形狀。那麼,首先要確定二維陣列的行數與列數。很明顯行數在輸入引數已經給出,我們要求得的就是其列數,設行數為r,輸入的字串長度為sLen。可以得知:
每兩列的字元數:r+(r-2)=2r-2

則,所需的列數為:sLen/(2r-2)+1。
接下來將第一個字元存入陣列的[0][0]位置,可以發現,豎著存時,每存r-1個數後,儲存的方向相反,列數+1。設定一個計數器與一個符號變數,每當計數器計數到2時,符號反向,列數+1。其餘情況則行數+=符號變數。
最後遍歷一遍二維陣列即可得到答案。

def convert(s, r):  # s:字串 r:行數
    if len(s) == 0 or r < 2:
        return s
    res = ""  # 存放結果
    sLen = len(s)  # 所給字串的長度
    cols = 2*sLen //
(2 * r - 2) + 1 mtx = [["" for _ in range(cols)] for _ in range(r)] a, b = 0, 0 # mtx中的座標 mtx[0][0] = s[0] count = 0 symbol = +1 for x in s[1:]: if count == 2: count = 0 symbol = -symbol b += 1 a = a + symbol mtx[
a][b] = x count += 1 for x in mtx: # 遍歷一次mtx for y in x: if y != "": res += y return res

缺點:時間複雜度與空間複雜度都較高,有優化的空間

思路2:
有沒有辦法只遍歷一次字串就得到我們想要的結果呢?有。
我們最終需要得到的只是一個字串,並不需要建立二維陣列儲存,不需要得知其具體圖形,只需要知道每一行有什麼字元即可。遍歷一次字串,每一行所求序列與按遍歷先後加入該行的序列相同。即,每次將遍歷到的字元按先後加入其所在的行數即可。解法如下:

def convert(self, s: str, numRows: int) -> str:
        if len(s) == 0 or r < 2:
            return s
        res = ["" for _ in range(numRows)]
        i, flag = 0, -1
        for c in s:
            res[i] += c
            if i == 0 or i == numRows - 1: 
            	flag = -flag
            i += flag
        return "".join(res)