问题描述
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。。
示例 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
Sol 1: (等差数列)
class Solution:
def convert(self, s, numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
tr=""
if numRows==1: return s
for i in range(numRows):
j=i
if i==0 or i==numRows-1:
while(j<len(s)):
tr=tr+s[j]
j=j+2*numRows-2
else:
while(j<len(s)):
tr=tr+s[j]
j=j+2*numRows-2-2*i
if(j<len(s)):
tr=tr+s[j]
j=j+2*i
return tr
从上式的三排和四排的情况,可以找出第一行和最后一行的规律是
,代表的是下一个词的位置。同理,除首末行之外的行的规律是,以及(没错,会多插一个位置,可以根据画图知道)。
运行时间:216ms 内存占用:6.6M
Sol 2: (压缩矩阵)
class Solution:
def convert(self, s, numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
if numRows == 1:
return s
zigzag = ['' for i in range(numRows)] # 初始化zigzag为['','','']
row = 0 # 当前的行数
step = 1 # 步数:控制数据的输入
for c in s:
if row == 0:
step = 1
if row == numRows - 1:
step = -1
zigzag[row] += c
row += step
return ''.join(zigzag)
这个方法如下表所示:
参考https://www.cnblogs.com/mzct123/p/5914383.html
1 | 7 | ||||
---|---|---|---|---|---|
2 | 6 | 8 | 12 | ||
3 | 5 | 9 | 11 | ||
4 | 10 |
压缩后:
1 | 7 | ||
---|---|---|---|
2 | 6 | 8 | 12 |
3 | 5 | 9 | 11 |
4 | 10 |
这样一来就可以通过调整step来根据加入每个词。
运行时间:92ms 内存占用:6.6M