Difficulty: 中等
將一個給定字串根據給定的行數,以從上往下、從左到右進行 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);
範例 1:
輸入: s = "LEETCODEISHIRING", numRows = 3
輸出: "LCIRETOESIIGEDHN"
範例 2:
輸入: s = "LEETCODEISHIRING", numRows = 4
輸出: "LDREOEIIECIHNTSG"
解釋:
L D R
E O E I I
E C I H N
T S G
純模擬,不願找規律🤣 二維陣列的方法大部分人都能想到,就看怎麼優化了。
題目分析:
L D R
E O E I I
E C I H N
T S G
可以簡化為
L D R
E O E I I
E C I H N
T S G
(所以說Z字排列和N字排列差不多就是一回事
每numRows*2-2
個數為一組,分兩列往新列表裡裝(第二列別忘了有空白),新列表中每隔numRows個數就是同一行,就這樣遍歷新列表,得到所求字串。
遇到的問題:
'分隔符'.join(含字串列表)
字串.split('分隔符')
object[start_index:end_index:step]
:當step為負時,起點值應該比終點值大(一開始忘了,切出來是空的…太菜了)。 看這個複習一下扁平二維陣列的結構:
class Solution(object):
def convert(self, s, numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
if numRows<2:
return s
l=[]
s=list(s)
#產生新列表(實際上是扁平化的二維陣列)
while len(s)>=numRows*2-2:
l+=s[:numRows]
s=s[numRows:]
l+=['0']+s[:numRows-2][::-1]+['0']
s=s[numRows-2:]
if len(s)<=numRows:
l+=s
else:
l+=s[:numRows]
s=s[numRows:]
l+=['0']*(numRows-2-len(s)+1)+s[::-1]#前邊用0補全
#讀取新列表
L=[]
for k in range(numRows):
L+=l[k::numRows]#一行
return ''.join(''.join(L).split('0'))
讚美這篇大佬寫的模擬,利用flag控制每個元素加入哪一行,很巧妙。⬇程式碼
class Solution:
def convert(self, s: str, numRows: int) -> str:
if numRows < 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)