拿到题目的后最容易想到就是先转换成Z字型再添加,此种方法不做赘述,效率一般。其次能够想到利用数学规律来当索引直接变换,一般规律如下
易得有n行,m个z时字符串长度为(2n-2)m+n,其中有
- 第一行与最后一行只有m+1个,其他为2*m+1个
- 每一行第一列均有且只有一个
- 第二行到第n-1行的非首列(第i行第j列)后的每两个数字,都相对(2n-2)*j+1对称,分别为(2n-2)*j+1+i与(2n-2)*j+1-i
结合给出的字符串不一定刚好组成m个Z字,可能不全,加入判断写出代码如下
class Solution:
def convert(self, s: str, numRows: int) -> str:
if not s:
return ""
if numRows == 1:return s
res = ""
m = int((len(s)-numRows)/(2*numRows-2)) + 1
for i in range(numRows):
for j in range(m+1):
if i == 0 or i == numRows-1:
if (2*numRows-2)*j+i < len(s):
res += s[(2*numRows-2)*j+i]
elif j == 0:
if (2*numRows-2)*j+i <len(s):
res += s[(2*numRows-2)*j+i]
else:
if (2 * numRows - 2) * j - i < len(s):
res += s[(2 * numRows - 2) * j - i]
if (2 * numRows - 2) * j + i < len(s):
res += s[(2*numRows-2)*j + i]
return res
效率一般,打败50%左右
在题解里面看到另外一种解法,也是找规律,但是实现方法不同,即以(2n-2)为一片断来判断添加,代码如下
def convert(s: str, numRows: int):
if not s:
return ""
if numRows == 1: return s
split_s_len = numRows * 2 - 2
data = []
n = len(s)
for i in range(0, n, split_s_len):
data.append(s[i:i + split_s_len])
# print(data)
res = ""
for i in range(numRows):
for tmp in data:
if i < len(tmp):
if i == 0 or i == numRows - 1:
res += tmp[i]
else:
res += tmp[i]
if split_s_len - i < len(tmp):
res += tmp[split_s_len - i]
return res
时间复杂度打败百分之七八十左右,相对上述解法减少了很多判断与求索引的操作