将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
之后,输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
示例 1:
输入:s = “PAYPALISHIRING”, numRows = 3
输出:“PAHNAPLSIIGYIR”
示例 2:
输入:s = “PAYPALISHIRING”, numRows = 4
输出:“PINALSIGYAHRPI”
示例 3:
输入:s = “A”, numRows = 1
输出:“A”
最开始看到,“???什么东西?Z ??”。仔细看下,其实就是找规律。
- 第 0 行,k * 2 * (n - 1)
- 第 n-1 行,k * 2 * (n - 1) + (n - 1)
- 内部 i 行,k * 2 * (n - 1) + i 以及(k + 1) * 2 * (n - 1) - i
思路一:逐行遍历,首先访问 行 0 中的所有字符,接着访问 行 1,然后 行 2,依此类推…
def convert(s, num):
if num == 1:
return s
nleng = 2 * (num - 1) # nleng 是判断、添加元素的关键
news = ""
for i in range(num): # 逐行遍历
j = 0
while j + i < len(s):
news += s[j+i]
if i not in [0,num-1] and j + nleng - i < len(s): # 中间行
news += s[j + nleng-i] # (k + 1) * 2 * (n - 1) - i
j += nleng
return news
思路二:从左到右迭代 s,将每个字符添加到合适的行。使用当前行和当前方向这两个变量对合适的行进行跟踪。注意第0行、第n-1行时,方向的改变。
def convert(s, num):
if num == 1:
return s
ret, i, k = ['' for i in range(num)], 0, 1 # i:行数,k:方向和步长
for el in s:
ret[i] += el
i += k
if i in [0, num-1]: # 方向改变
k = -k
return ''.join(ret)