题目:
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 s, int numRows);
例子:
Example 1:
Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"
Example 2:
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P I N
A L S I G
Y A H R
P I
问题解析:
将字符串s以Z字形排列成给定的行数之后从左往右,逐行读取字符。
思路标签
找规律
解答:
1.模拟寻找规律
- 通过观察,我们可以发现:
- 第0行和最后一行中,前一个下标的值和后一个下标的值相差
2*nRows-2
,以第0行为例,前一个下标为0,后一个下标为 0+2*4-2=6; - 中间行中,前一个下标的值和后一个下标的值需要根据这个下标是该行中的奇数列还是偶数列来计算。以平时的习惯来计算,因此,行和列的开始值都是0。
- 以第2行为例,第一列下标是0,后一个下标所处列为1,是奇数列,因此从这个下标到下一个下标相差的值是它们所处的行i下面的所有行的点的个数,即2 * (nRows – 1 – i)。
- 当所处的是偶数列,从这个下标到下一个下标相差的值其实是它们所处的行i上面的所有行的点的个数,即2 * i。
class Solution {
public:
string convert(string s, int nRows) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if (nRows <= 1 || s.length() == 0)
return s;
string res = "";
int len = s.length();
for (int i = 0; i < len && i < nRows; ++i)
{
int indx = i;
res += s[indx];
for (int k = 1; indx < len; ++k)
{
//第一行或最后一行,使用公式1:
if (i == 0 || i == nRows - 1)
{
indx += 2 * nRows - 2;
}
//中间行,判断奇偶,使用公式2或3
else
{
if (k & 0x1) //奇数位
indx += 2 * (nRows - 1 - i);
else indx += 2 * i;
}
//判断indx合法性
if (indx < len)
{
res += s[indx];
}
}
}
return res;
}
};