Z 字形变换
题目链接:
题目描述:

题目示例:

解法(模拟 + 找规律)
思路分析
这道题的核心在于找到字符排列的周期性规律。假设行数 numRows 为 4,我们可以画出 Z 字形的下标变化:
0 6 12
1 5 7 11
2 4 8 10
3 9
不难发现,数据是以 2 * numRows - 2 为一个周期进行循环的。对于每一行,我们需要确定该行在字符串中的索引位置。
- 第一行和最后一行:下标间隔固定为
2 * numRows - 2。 - 中间行:除了首尾元素外,每个周期内包含两个字符,分别位于当前周期的起始偏移量和结束偏移量处。
具体来看,第 k 行(非首尾)的两个下标分别为 i 和 j,其中 i 是主对角线上的点,j 是斜线回上的点。它们在一个周期内的相对位置是对称的。
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 = 0; i < n; i += d) {
ret += s[i];
}
// 2. 处理中间的几行
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];
}
}
// 3. 处理最后一行
for (int i = numRows - 1; i < n; i += d) {
ret += s[i];
}
return ret;
}
};
注意:这里使用双指针逻辑处理中间行,
i对应向下走的步长,j对应向上走的步长。当i或j超出字符串长度时停止添加,确保边界安全。
外观数列
题目链接:
题目描述:

题目示例:


解法(模拟)
思路分析
外观数列(Count and Say)的本质是'读'出前一项的内容。每一项都是对前一项连续相同字符的描述:统计个数 + 字符本身。
例如:
- 第 1 项:"1"
- 第 2 项:"11" (1 个 1)
- 第 3 项:"21" (2 个 1)
- 第 4 项:"1211" (1 个 2,1 个 1)
我们可以通过迭代的方式,利用双指针扫描当前字符串,统计连续相同字符的数量,拼接成下一项。直到迭代到第 n 项为止。
C++ 代码实现
class Solution {
public:
string countAndSay(int n) {
string ret = "1";
for (int i = 1; i < n; i++) {
string tmp;
for (int left = 0, right = 0, count = 0; right < ret.size(); ) {
while (right < ret.size() && ret[left] == ret[right]) {
right++;
}
tmp += to_string(right - left) + ret[left];
left = right;
}
ret = tmp;
}
return ret;
}
};
关键点:内层循环通过移动
right指针来统计连续相同字符的长度,left记录当前段的起始位置。每次统计完一段后,将数量转换为字符串并追加字符,然后更新left继续处理下一段。


