【leetcode系列】【py3】【中等】Z 字形变换
题目:
原题链接: https://leetcode-cn.com/problems/zigzag-conversion/
解题思路:
抛开原始字符串,直接使用字符串编号,转换后的排列如下:
3阶:
0 | 4(0+4) | 8(4+4) | 12(8+4) | 16(12+4) | |||||
1 | 3(1+2) | 5(3+2) | 7(5+2) | 9(7+2) | 11(9+2) | 13(11+2) | 15(13+2) | 17(15+2) | 19(17+2) |
2 | 6(2+4) | 10(6+4) | 14(10+4) | 18(14+4) |
4阶:
0 | 6(0+6) | 12(6+6) | 18(12+6) | ||||||
1 | 5(1+4) | 7(5+2) | 11(7+4) | 13(11+2) | 17(13+4) | 19(17+2) | |||
2 | 4(2+2) | 8(4+4) | 10(8+2) | 14(10+4) | 16(14+2) | 20(16+4) | |||
3 | 9(3+6) | 15(9+6) | 21(15+6) |
3阶的可能不太明显,4阶比较明显,用4阶的为例
每行的下标间隔总数为6(2 * (4 - 1)),将每行的间隔分为左间隔和右间隔,变化如下:
左间隔 | 右间隔 |
---|---|
6 | 0 |
4 | 2 |
2 | 4 |
0 | 6 |
每往下一行,左间隔-2,右间隔+2
每行的第一个字符的编号就是行号,然后根据行号,进行左右间隔轮换跳转获取字符
每个字符只循环了一次,时间复杂度为O(n)
代码实现:
class Solution:
def convert(self, s: str, numRows: int) -> str:
if 0 == len(s):
return s
total = max(2 * (numRows - 1), 1)# 使用list的原因,是因为''.join()的效率,比str的+效率要高
res_str = []
cycle_num = 0
for row in range(0, numRows):
index = row
if index >= len(s): break
res_str.append(s[index])
left = total - 2 * row
right = 2 * row
while index < len(s):
cycle_num += 1
if 0 != left:
index += left
if index < len(s): res_str.append(s[index])if 0 != right:
index += right
if index < len(s): res_str.append(s[index])
return ''.join(res_str)