每日一練——Z 字形變換(python)
阿新 • • 發佈:2020-12-12
問題描述:
將一個給定字串根據給定的行數,以從上往下、從左到右進行 Z 字形排列。
比如輸入字串為 “LEETCODEISHIRING” 行數為 3 時,排列如下:
之後,你的輸出需要從左往右逐行讀取,產生出一個新的字串,比如:“LCIRETOESIIGEDHN”。
請你實現這個將字串進行指定行數變換的函式。
思路1:
看到題目的第一時間,想到要使用二維陣列來儲存最終排列的形狀。那麼,首先要確定二維陣列的行數與列數。很明顯行數在輸入引數已經給出,我們要求得的就是其列數,設行數為r,輸入的字串長度為sLen。可以得知:
每兩列的字元數:r+(r-2)=2r-2
接下來將第一個字元存入陣列的[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)