思路分析
-
处理特殊情况:
- 如果
numRows
为1,那么字符排列与原字符串相同,无需进行转换,直接返回原字符串。
- 如果
-
定义和初始化变量:
n
:字符串长度。k
:一个完整的“V”字形周期长度,计算公式为2 * numRows - 2
。a
:一个包含numRows
个字符串的向量,用于存储每一行的字符。
-
遍历字符串并填充每行字符:
- 遍历字符串中的每个字符,通过计算确定字符属于哪一行,然后将该字符添加到对应的行。
- 行的计算方式为
min(k - i % k, i % k)
:i % k
计算出字符在周期中的位置。min(k - i % k, i % k)
用于确定字符属于哪一行。这个公式确保在一个周期内正确地将字符分配到对应的行。周期前半部分行号逐渐增加,后半部分行号逐渐减少,形成锯齿形。
-
合并所有行的字符形成最终结果:
- 使用
accumulate
函数将所有行的字符串连接起来,形成最终结果。
- 使用
class Solution {
public:
string convert(string s, int numRows) {
// 如果行数为1,直接返回原字符串,因为Z字形转换在这种情况下没有意义
if (numRows == 1) return s;
// 获取字符串长度
int n = s.size();
// 计算Z字形排列的周期长度(一个完整的V字形的字符数)
int k = 2 * numRows - 2;
// 创建一个向量,存储每行的字符
vector<string> a(numRows);
// 遍历字符串中的每一个字符
for (int i = 0; i < n; i++) {
// 计算字符属于哪一行,使用min(k - i % k, i % k)来确定
// i % k计算出字符在当前周期中的位置,然后用min函数确定行号
a[min(k - i % k, i % k)] += s[i];
}
// 使用accumulate函数将所有行的字符串连接起来,形成最终结果
return accumulate(a.begin(), a.end(), string(""));
}
};