一、问题描述
The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
P A H N
A P L S I I G
Y I R
And then read line by line: “PAHNAPLSIIGYIR”
Write the code that will take a string and make this conversion given a number of rows:
string convert(string text, int nRows);
convert(“PAYPALISHIRING”, 3) should return “PAHNAPLSIIGYIR”.
二、解题思路
给定一个字符串,这个字符串是将字符串按照Z型排布得到的顺序,要求的是逐行读取该Z型字符串。如果选择初始化一个二维数组并逐一将字符填进去,则会浪费大量空间,且最终需要遍历该二维数组,时间开销也大。
比较好的办法是,不用将字符串进行显式的Z型排列,而是通过寻找这种排布下的规律来解决问题,在这种Z型排布中,其实每个字符都可以通过它的序号和函数参数numRows计算出它经过排列后所在的行数。这里可以通过画图和敏感性发现可以把每2 * (numRows - 1)个字符作为一组,因为2 * (numRows - 1)是使得组内字符所在位置不等效的最大值,通过寻找规律,同样可以得出,对于字符串的第i位,在字符串经过Z型排列后s[i]所在的行数可以表示为
numRows - 1 - abs(numRows - 1 - (i % group))
每一行单独作为一个字符串,最后将所有字符串拼接起来,就得到最终结果(numRows <= 1时另做考虑)
三、C++代码
class Solution {
public:
string convert(string s, int numRows) {
if (numRows <= 1) return s;
string* rows = new string[numRows];
int group = 2 * (numRows - 1);
for (int i = 0; i < s.length(); i++) {
rows[numRows - 1 - abs(numRows - 1 - (i % group))] += s[i];
}
string result;
for (int j = 0; j < numRows; j++) {
result += rows[j];
}
return result;
}
};