题目要求:
将字符串 "PAYPALISHIRING"
以Z字形排列成给定的行数:
P A H N
A P L S I I G
Y I R
之后从左往右,逐行读取字符:"PAHNAPLSIIGYIR"
实现一个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = "PAYPALISHIRING", numRows = 3
输出: "PAHNAPLSIIGYIR"
示例 2:
输入: s = "PAYPALISHIRING", numRows = 4
输出: "PINALSIGYAHRPI"
解释:
P I N
A L S I G
Y A H R
P I
C++代码:
class Solution {
public:
string convert(string s, int numRows) {
if (numRows <= 1)
return s;
const int len = (int)s.length();
string *str = new string[numRows];
int row = 0, step = 1;
for (int i = 0; i < len; ++i)
{
str[row].push_back(s[i]);
if (row == 0)
step = 1;
else if (row == numRows - 1)
step = -1;
row += step;
}
s.clear();
for (int j = 0; j < numRows; ++j)
{
s.append(str[j]);
}
delete[] str;
return s;
}
};
结果:
解析:
代码读起来也是比较清晰的。
首先如果numRows≤1的话,就直接返回原来的字符串s
如果大于1,我们重新定义一个str字符串,用来装重新排好序的字符。
这个str一共有numRows行,我们通过一个for循环来对原字符串s中的每个元素逐一遍历操作,因此时间复杂度是O(n)级别的。
row也就是numRows行,假设一共需要分4行,那么row=0、1、2、3;
一开始往下填充字符时,step=1,也就是正向(我们把向下当正向,向上的时候当反向)
所以row从0->3时,step=1,然后就从原字符串s中依次取出当前的字符,放入str中,
当row遍历到3(numRows-1)时,这时候改step=-1,因为已经到最底了,我们要逐一从下往上遍历,具体操作跟之前一样;
然后row从3->0时,step=-1;
当row又重新回到0(row == 0)时,step又变回1,因为已经到最顶了,接下来又要重复之前的步骤,从上到下遍历,存当前元素进str。
当对字符串s中的所有字符逐一遍历完成后,就会按照从上到下的顺序排序好,这时候只需要按顺序,从str里按行读取每一行的所有字符,就可以得到最终排序的结果。