6. ZigZag Conversion
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)
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 s, int numRows);
Example 1
:
Input
: s = "PAYPALISHIRING", numRows = 3
Output
: "PAHNAPLSIIGYIR"
image.png
Example 2
:
Input
: s = "PAYPALISHIRING", numRows = 4
Output
: "PINALSIGYAHRPI"
Explanation
:
题目大意:
给定一个字符串s与数字numRows,将s进行之字形的numRows排列后,将它们逐行重组并输出。
解题思路:
没什么算法,就是看图找规律。
image.png
可以看出字符串按之字形排列的时候会有一个周期,当numRows=3时,4个字符为一个周期;当numRows=4时,6个字符为一个周期;当numRows=5时,8个字符为一个周期,可以归纳出周期cycle=2*numRows-2。
其实也可以由图像观察得出,把每一个周期中间的字符归到一列可以看出其实就是两列字符再去掉第一行和第二行而已,推断不难。
找出周期概念就简单了,逐行输出,头尾两行就是首字符加上周期即可,中间每行再另作观察。
观察得出每行的[n, n+1]
(n>=1)个周期之间的字符与n+1
个周期的第一个字符(下标为j
)总是相差j-2*(当前行在中间行数的序号),输出即可,有点拗口,可以写下当numRows=5时的字符排列观察一下。
解题代码:
class Solution {
public:
string convert(string s, int numRows)
{
if (numRows < 2) return s;
string res;
int cycle = 2 * numRows - 2, flag = 0, count = 0, second, size = s.size();
for (int i = 0; i < numRows;++i)
{
for (int j = i; j < size; j = j + cycle)
{
res = res + s[j];
second = j + cycle - 2 * i;
if (i != 0 && i != numRows - 1 && second < size)
res = res + s[second];
}
}
return res;
}
};