算法模拟实战:Z 字形变换与外观数列详解
本文聚焦于两道经典的算法模拟题,通过代码实现与逻辑推导,深入剖析字符串处理中的周期规律与迭代统计技巧。
Z 字形变换
题目链接: 6. Z 字形变换 - LeetCode
题目描述:
将给定字符串 s 根据给定的行数 numRows,以从上往下、从左到右进行 Z 字形排列。

示例:
输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"
思路分析
这道题的核心在于找到下标的变化规律。当 numRows 为 4 时,字符的排列呈现出明显的周期性。
观察下标序列可以发现,数据是以 2 * numRows - 2 为一个周期进行循环的。我们可以将问题拆解为三部分处理:首行、中间行、末行。
- 首行与末行:这两行的下标间隔固定,均为
2 * numRows - 2。例如第一行是0, d, 2d...(其中d为周期)。 - 中间行:对于第
k行(0 < k < numRows - 1),每个周期内包含两个字符。第一个字符的下标是i + k,第二个字符的下标是i + (d - k)。我们需要交替添加这两个位置的字符。
这种分情况讨论的方法避免了复杂的数学映射,直接模拟了读取过程,逻辑清晰且易于实现。
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();
// 1. 处理第一行
for (int i = ; i < n; i += d) {
ret += s[i];
}
( k = ; k < numRows - ; k++) {
( i = k, j = d - k; i < n || j < n; i += d, j += d) {
(i < n) ret += s[i];
(j < n) ret += s[j];
}
}
( i = numRows - ; i < n; i += d) {
ret += s[i];
}
ret;
}
};







