题目描述
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 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
解题思路
这题一开始我就想用公式算出输出字符串中每一个字符对应到原字符的位置,这样找规律,找了半天,发现有点难受,如输出的第一个为原字符串的0元素,第二个为
0
+
2
∗
(
n
u
m
R
o
w
s
−
1
)
0+2*(numRows-1)
0+2∗(numRows−1),然后第三个
.
.
.
...
...,我这样下去,越理越乱。就放弃这个想法了。
后来看到这个Z字行,动态的将原字符串一个一个放成这样,有点像我在阳台拿着花洒给一排盆栽浇水,我从第一个花盆浇水,浇到最后一个花盆后,(我的习惯)我原路返回,从最后一个花盆开始往回浇水,然后浇到第一个花盆,花洒里的水还有,那接着从第一个到最后一个,再从最后一个到第一个,
.
.
.
...
...,直到花洒里的水用光为止。
这里的水可以类比为原字符串,而盆栽则可以类比为行数。问题就这样解决了!
解题代码
class Solution:
def convert(self,s:str,numRows:int) -> str:
"""
初始化numRows个字符串,
"""
if numRows <=1:
return s
result = ["" for _ in range(numRows)] #有多少个花盆要浇水
cursor = 0 #当前花洒浇水的花盆
direction = 1 #-1 代表反方向,1代表正方向
for i in range(len(s)):
result[cursor] += s[i]
if direction==1: #往前浇水
cursor +=1
else: #往后浇水
cursor -= 1
if cursor>=numRows-1: #浇到最后一个花盆时,要往回浇水
direction = -1
if cursor <=0: #浇到第一个花盆时,就要往后浇水
direction = 1
return "".join(result)
提交结果
总结
我后来看了一下官网的解答提示,代码竟然惊人的相似,思想也比较相近,但是官网解释的有点晕,不管官网的代码还是很精炼的。终于有点感觉了,我觉得算法有时候可以类比生活中的一些事情,这样思路就开阔了。