问题描述:将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。(输入字符串s和行数numRows,按新的顺序输出)
例如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
方法一:找规律
1.模块化
我们可以从上面例子的形式看出由于这些Z是重叠的,所以我们可以把“一竖”加“一提”看作一个小模块,比如可以将"LEET"当作第一个小模块,将“CODE”当作第二个小模块······
2.确定模块的大小
先找一个代表性更强的例子:
L D R
E O E I I
E C I H N
T S G
我们可以总结出一个小模块的“一竖”总比“一提”多2个字符,而“一竖”的字符个数又是行数numRows故可以由此推断出小模块的大小为:
batch_z = 2*numRows-2
3.确定输出关系
按行输出的话(以第二个例子为例)
第0行第0,1,2, 3个元素有0%6=0,6%6=0,12%6=0,18%6=0
第1行第1,1,2, 3个元素有1%6=1,7%6=1,13%6=1,19%6=1
···
可由此推出输出顺序
4.程序
class Solution:
def convert(self, s: str, numRows: int) -> str:
new_s = []
if numRows == 0:
return None
elif numRows == 1:
return s
batch_z = 2*numRows-2 #一条竖边和一条斜边构成一个z
vertical_z = int((batch_z+2)/2) # 竖边的长度
oblique_z = batch_z-vertical_z #斜边的长度
for j in range(0,vertical_z):
for i in range(0,len(s)):
if i%batch_z == j or i%batch_z == batch_z-j:
new_s.append(s[i])
new_s = ''.join(new_s) # 将列表里的元素放在一个字符串里面
return new_s
if __name__ == '__main__':
solution1 = Solution()
s = "12345678"
#s = "abcdefghi"
#s = "a"
print("s=",s)
numRows = 1
new_s = solution1.convert(s,numRows)
print(new_s)