题目描述
将一个给定字符串 s 根据给定的行数 numRows,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING",行数为 3 时,排列如下:
cpp
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左到右逐行读取,产生一个新的字符串,比如:"PAHNAPLSIIGYIR"。
请你实现这个将字符串进行指定行数变换的函数:
解法:模拟找规律

我们先用下标来代替具体数字,更好的找到规律
找规律 + 按行遍历
观察 Z 字形排列,可以发现一个周期:
bash
以 numRows = 4 为例:
第0行: 0 6 12 18
第1行: 1 5 7 11 13 17
第2行: 2 4 8 10 14 16
第3行: 3 9 15
周期 d = 2 * numRows - 2 = 6

第一行和最后一行
数字的变换都是再前面一个,数字的基础上加上一个公差
第一行:kd
第n-1行:(n-1)+kd;
非第一行和最后一行
将两个两个看成一组,都是每一组相对应的位置上的数加上公差d,可以发现组的两个数相加恰好为公差
{i+kd , d-i+kd}
找到规律,我们按行开始填写即可
cpp
#include<string>
class Solution {
public:
string convert(string s, int numRows) {
if (numRows == 1 || s.empty()) return s;
//计算公差d
int d=2*numRows-2;
int n=s.size();
string s1;
int k=n/numRows+1;
for(int j=0;j<k;j++)
{ if(j*d<n)
s1+=s[j*d];
}
for(int i=1;i<numRows-1;i++)
for(int j=0;j<k;j++)
{
if(i+j*d<n)
s1+=s[i+j*d];
if(d-i+j*d<n)
s1+=s[d-i+j*d];
}
for(int j=0;j<k;j++)
{
if(numRows-1+j*d<n)
s1+=s[numRows-1+j*d];
}
return s1;
}
};