Z 字形变换
题目链接: 6. Z 字形变换 - LeetCode
题目描述: 将字符串按照指定行数进行 Z 字形排列,然后按行读取生成新字符串。
示例: 输入:s = "PAYPALISHIRING", numRows = 3 输出:"PAHNAPLSIIGYIR"
解题思路
这道题的核心在于找到字符在 Z 字形中的位置规律。当行数 numRows 确定后,整个排列呈现出周期性。周期长度为 2 * numRows - 2。
我们可以把每一行看作一个独立的序列来处理:
- 首行和末行:字符间隔固定为周期长度
d = 2 * numRows - 2。 - 中间行:除了首尾的间隔外,每两个字符之间还有一个额外的字符,其位置可以通过对称性计算得出。具体来说,第
k行的字符下标满足i和d - i的交替出现模式。
基于这个观察,我们不需要真正构建二维数组,只需遍历原字符串,根据当前字符所在的行号直接拼接到结果中即可。这样空间复杂度可以优化到 O(1)(不计结果字符串)。
C++ 代码实现
class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1) return s;
string ret;
int d = 2 * numRows - 2;
int n = s.size();
// 处理第一行
for (int i = 0; i < n; i += d) {
ret += s[i];
}
// 处理中间几行
for (int k = 1; k < numRows - 1; k++) {
for (int i = k, j = d - k; i < n || j < n; i += d, j += d) {
if (i < n) ret += s[i];
if (j < n) ret += s[j];
}
}
( i = numRows - ; i < n; i += d) {
ret += s[i];
}
ret;
}
};


