碎碎念:看了官方對規律的描述,發現它的規律與我的規律的描述差距挺大的。我的規律是相對每一行來說的,而官方的規律總是相對思路numrows
來描述的,所以更容易表達出來,因為numrows
是個定值!而我找規律的基準是變化的,難怪沒有繞出來,沒法寫出來…不過對於官方的規律,也不太容易想到吧。
從左向右迭代原始字串,將每個字元都直接儲存到其位於 z 字形圖案中的那一行。
演算法演算法的關鍵在於如何找準每個字元應該儲存到的行,我們觀察示例可知,儲存了乙個字元後,要麼就是在其下一行繼續儲存下乙個字元,要麼就是在其上一行繼續儲存下乙個字元(注意,無須在意如何完全將那個z字形打出來!關鍵是按照z字形進行字元的重新儲存!不要想偏了),所以我們可以使用變數currow
表示當前行,然後按照規則分別對currow
進行加1或減1操作。那麼,這裡的「規則」是怎樣的呢?答:從第一行開始,儲存完乙個字元後每次都要進行加1操作,知道儲存到了最後一行,然後開始進行減1操作。所以我們可以對第一行和最後一行設定乙個goingdown
標誌;goingdown
為true
時,表示改變當前行的操作是加1,goingdown
為false
時,表示改變當前行的操作是減1。然後我們可以借助乙個列表rows
儲存這numrows
行的每行的字串,當然,需要初始化這些字串為空。此時,currow
就是rows
的下標,所以z字形的某行字串就是rows[currow]
。
def
convert
(s, numrows)
:if numrows ==1:
return s
rows =[''
]*min(numrows,
len(s)
)# 相當於建立了乙個「陣列」
currow =
0'''
goingdown為true: currow為前(numrows - 1)的情況
goingdown為false: currow為最後一行numrows的情況
'''goingdown =
false
for ch in s:
rows[currow]
+= ch
if currow ==
0or currow == numrows -1:
goingdown =
(not goingdown)
''' goingdown為true時,下一當前行直接為(currow + 1);
goingdown為false時,下一當前行需要跳轉到前一行,所以(currow - 1)
'''currow +=(1
if goingdown ==
true
else-1
) s_return =
''.join(rows)
return s_return
print
(convert(
"leetcodeishiring",3
))
複雜度分析:思路按照與逐行讀取 z 字形圖案相同的順序訪問字串。
演算法對於z字形中每一行的第k個字元(k從0開始),有:
優化觀察上面的規律,可以發現:第一行
(i = 0)
以及最後一行(i = numrows - 1)
中的字元的索引又可以歸一成:k * ( 2 * numrows - 2 ) + i
。Z字形變換
題目 將字串 paypalishiring 以z字形排列成給定的行數 p a h n a p l s i i g y i r 之後從左往右,逐行讀取字元 pahnaplsiigyir 思路 通過從左向右迭代字串,我們可以輕鬆地確定字元位於 z 字形圖案中的哪一行。演算法 我們可以使用 min num...
Z 字形變換
將乙個給定字串根據給定的行數,以從上往下 從左到右進行 z 字形排列。輸入 s leetcodeishiring numrows 4 輸出 ldreoeiiecihntsg l d r e o e i i e c i h n t s g 注釋思路 class solution 有了列數和行數,總個數...
Z 字形變換
將乙個給定字串根據給定的行數,以從上往下 從左到右進行 z 字形排列。比如輸入字串為 leetcodeishiring 行數為 3 時,排列如下 l c i r e t o e s i i g e d h n之後,你的輸出需要從左往右逐行讀取,產生出乙個新的字串,比如 lciretoesiigedh...