Z 字形变换
字符串 模拟 数学题目描述
将一个给定的字符串 s 根据给定的行数 rows,以从上往下、从左到右的 Z 字形排列。之后按照逐行阅读的顺序返回拼接后的字符串。
例如,输入字符串 "PAYPALISHIRING",行数为 4 时,Z 字形排列如下:
最终结果为 "PINALSIGYAHRPI"。
思路分析
解法一:模拟法
最直观的做法是模拟 Z 字形书写的过程:
- 创建一个长度为
rows的数组,每个元素代表 Z 字形中的一行。 - 遍历字符串中的每个字符,将它追加到当前行。
- 通过一个
goingDown变量控制方向:到达首行或末行时掉头。 - 最终把所有行拼接起来就是结果。
解法二:数学构造法(进阶)
不需要模拟遍历过程,而是直接通过数学公式计算出每个字符在原字符串中的索引位置。
核心观察:一个完整的 Z 字形周期长度为 cycle = 2 * (rows - 1)。在每个周期中:
- 下行阶段:每一行都会被经过一次,索引为
j + row。 - 上行阶段:非首行、非末行会被再经过一次,索引为
j + cycle - row。
因此只需逐行遍历,按公式直接取出字符拼接即可。
示例代码
复杂度分析
两种解法的复杂度相同:
- 时间复杂度:
O(n),其中n是字符串长度。每个字符恰好被访问一次。 - 空间复杂度:模拟法为
O(n)(需要存储各行字符串);数学构造法也为O(n)(结果字符串)。
示例演示
以 s = "PAYPALISHIRING"、rows = 4 为例,周期 cycle = 2 * (4 - 1) = 6:
逐行拼接结果:"PINALSIGYAHRPI"。