这道题感觉没啥技术含量,只要你找到它的规律就可以做出来
我先将整个图形分成一组一组的小图形,我圈出来的算一组

如果一个Z的numRows是n,那么一组的size就是 2 * n - 2
我把整个Z字形分成三层

上面为第一层,在添加到新字符串中很容易,第一层的元素在字符串中的索引是
s[j * size], j 是 该元素是属于第几组(从0开始),size则是一组的大小中间若干层,可以看成是一对一对的元素, 设当前层高为i,也就是从上往下数第i行(从0开始),要添加到新字符串中的字符为 s[i + j * size] 和 s[size - i + j * size],后面的j * size 表示他是第几组的
最后一层和第一类类似,可以很快得出加入新字符串的字符为s[numRows - 1 + j * size]
class Solution
{
public:
string convert(string s, int numRows)
{
// numRows 等于1特殊情况,直接返回原数组
if (numRows == 1)
return s;
// 每个分组的大小
int size = 2 * numRows - 2;
// 字符串长度
int length = s.size();
// 一共有几个分组,向上取整
int n = ceil(double(s.size()) / double((2 * numRows - 2)));
string s1;
// 加入第1行
int j = 0;
while (j < n && j * size < length)
{
s1 += s[0 + j * size];
j++;
}
// 加入第 2 - numRows - 1 行
for (int i = 1; i < numRows - 1; i++)
{
int j = 0;
// 因为我们在求组数时,是向上取整,所以不能保证最后一组是完整的,但是可以保证前 n - 1组是完整的
while (j < n - 1)
{
s1 += s[i + j * size];
s1 += s[size - i + j * size];
j++;
}
// 单独考虑最后一组的索引是否越界
if (j == n - 1)
{
if (i + j * size < length)
s1 += s[i + j * size];
if (size - i + j * size < length)
s1 += s[size - i + j * size];
}
}
// 加入第numRows 行
j = 0;
while (j < n && numRows - 1 + j * size < length)
{
s1 += s[numRows - 1 + j * size];
j++;
}
return s1;
}
};

最后,虽然这题没技术含量,但是两次提交就过了好开心,第一次只是没有考虑 numRows = 1的特殊情况