题目
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"
.
思路
一个简单的例子,0~16排列成4行ZigZag形式:
0 6 12
1 5 7 11 13
2 4 8 10 14 16
3 9 15
对于函数string convert(string s, int numRows)
可以发现以下规律:
- 第0行与第numRows-1行,间隔为2*numRows-2;
- 中间1~numRows-2行,对于第i行第j列,在以上间隔的基础上,添加了j+2*numRows-2-2*i
此外,两点需要注意:
- 平凡情况,
s.size() <= numRows || numRows==1
,否则容易陷入死循环 - 中间的循环需要保证两种情况都不越界,但不是“且”的关系,否则容易漏掉元素,正确代码如下:
for (int i = 1; i <= numRows - 2; ++i) {
for (int j = i; j < n; j += 2 * numRows - 2) {
result.append(1, s[j]);
if (j + 2 * numRows - 2 - 2 * i<n)
result.append(1, s[j + 2*numRows - 2 - 2*i]);
}
}
解答
class Solution {
public:
string convert(string s, int numRows) {
string result;
int n = s.size();
if (n <= numRows||numRows==1)
return s;
for(int i = 0; i<n; i+=2*numRows-2)
result.append(1,s[i]);
for (int i = 1; i <= numRows - 2; ++i) {
for (int j = i; j < n ; j += 2 * numRows - 2) {
result.append(1, s[j]);
if(j + 2 * numRows - 2 - 2 * i<n)
result.append(1, s[j + 2 * numRows - 2 - 2 * i]);
}
}
for (int i = numRows-1; i<n; i += 2 * numRows - 2)
result.append(1, s[i]);
return result;
}
};