📅  最后修改于: 2023-12-03 15:06:08.528000             🧑  作者: Mango
在编程中,Z字形转换指将一个字符串按照“Z”字形排列成给定的行数,然后逐行逐个字符读取。例如,一个字符串 "PAYPALISHIRING",行数为 3,它会被排列成如下的形式:
P A H N
A P L S I I G
Y I R
然后按照行读取:"PAHNAPLSIIGYIR"
此主题总结了如何实现Z字形转换。在以下的讨论中,我们将通过一个示例字符串“PAYPALISHIRING”来进行说明。
大多数人都能独立想出数组模拟的算法,但思考它的时间可能会比单个字符管理者要长。
我们可以使用min(numRows,len(s))个列表来模拟将字符添加到合适的行中。从左到右迭代字符串s,将空余的字符串填入我们的字符串列表中的合适行中。每当行达到最后一行或第一行时,子串就应该反转。
我们可以使用一个flag变量来反转方向,当我们移动到第一行或最后一行时,我们将flag取反。
def convert(s: str, numRows: int) -> str:
if numRows == 1 or numRows >= len(s):
return s
res = ["" for _ in range(numRows)]
index, flag = 0, -1
for i in s:
res[index] += i
if index == 0 or index == numRows - 1:
flag = -flag
index += flag
return "".join(res)
当行数为numRows时,字符串s的遍历时间复杂度为O(N),这里的N是字符串长度。添加到列表中的时间复杂度为O(1),所以最终的时间复杂度为 O(N)。
使用了min(numRows,len(s))个字符串列表,所以空间复杂度为O(min(numRows,len(s)))。
按照与读取顺序相同的顺序访问字符串。首先访问行0中的所有字符,然后访问行1,然后行2,依此类推...对于所有整数k,
def convert(s: str, numRows: int) -> str:
if numRows == 1 or numRows >= len(s):
return s
n = len(s)
cycle_len = 2 * numRows - 2
res = []
for i in range(numRows):
for j in range(0, n - i, cycle_len):
res.append(s[j + i])
if i != 0 and i != numRows - 1 and j + cycle_len - i < n:
res.append(s[j + cycle_len - i])
return "".join(res)
遍历字符串s的时间复杂度为O(N),其中N是字符串长度。在转换中,我们按顺序访问每个字符,将它放入正确的行。因为每个字符正好被访问一次,所以时间复杂度是O(N)。
除了输出字符串之外,这种方法所需的空间复杂度较小。在生成输出字符串时,我们需要使用O(N)的空间来保存整个字符串。
以上就是Z字形转换的两种解法。在实现时,可以根据实际需要,从中选择一种较为简单或者适合的解法。