题目:
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
请你实现这个将字符串进行指定行数变换的函数:
参考代码:
def convert(self, s: str, numRows: int) -> str:
if numRows < 2:
return s
res = ["" for _ in range(numRows)]
i =0
flag = -1
for c in s:
res[i] += c
if i == 0 or i == numRows - 1:
flag = -flag
i += flag
return "".join(res)
借鉴:
1、索引不一定是单方向递增或递减,可双方向加或减,借助一个flag,可使得索引更加灵活,根据需要递增或递减。
2、创建空字符串列表: res = ["" for _ in range(numRows)]
3、join()的使用:"".join(res)
string convert(string s, int numRows);
本人的漂亮烂代码:
def convert(self, s: str, numRows: int) -> str:
if numRows == 1:
return s
res = ["" for i in range(numRows)]
i = 0
loop = numRows*2-2
while i < len(s):
mode = i%loop
if 0 <= mode < numRows:
index = mode
res[index] += s[i]
elif numRows <= mode < loop:
index = loop - mode
res[index] += s[i]
i += 1
result = ''
for c in res:
result += c
return result
反思:
1、每一行为一个字符串,总共numRows行,即定义拥有numRows个字符串的列表。
2、找规律:我们把每一个V字形上的元素个数作为一个循环,每一个循环都有numRows*2-2个元素。这样问题就转换成一个循环下的numRows个字符串赋值问题。
3、对于完整的一列,直接就是s[0],s[1]~s[numRows1],但是单个元素的列,需要再次找规律,发现loop减去s的index(取模后的)就是列表中字符串的index。
4、最后就是字符串列表中各字符串连接,输出。这里有个小技巧,可以直接使用join()函数。
5、join()将序列中的元素以指定的字符连接生成一个新的字符串。str.join(sequence)
比如:
>>> a=['a','bc','def','ghik']
>>> "".join(a)
'abcdefghik'
>>> '-'.join(a)
'a-bc-def-ghik'