题目描述:
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"
.
即用N字型的方式摆放字符(下 -> 右斜向上 -> 下 -> 右斜向上 ...), 然后从上往下, 从左往右输出字符串。
题目解析:
这道题蛮有意思的,首先的思路是使用一个二维数组,模拟字符串的摆放,但考虑变量nRows足够大时,最后扫描要输出的字符串时会遇到很多空白的位置,花费大量时间。
为此考虑更简单的方法,不妨把对应的下标画出来。并计算同一行相邻下标的间距。我写这一道题的解析的目的是,希望大家在做题前先找一下是否求解过程或答案存在规律:-)
0 1 2 3 1
0 2 4 6 2
1 3 5 2
0 4 8 4
1 3 5 7
2 6
0 6 12 6,6
1 5 7 11 13 4,2
2 4 8 10 14 2,4
3 9 15 6,6
0 10 10
1 9 11 8,2
2 8 12
3 7 13
4 6 14
5 15
很容易看出规律,对于nRows为n的例子,n = 1时,k = 1; n 不等于 1时, k = (n-1) * 2
第一行与最后一行的间隔为k, 其他行存在两个间距,和为k.
参考代码:
class Solution {
public:
string convert(string s, int numRows) {
int k = (numRows-1) * 2;
if (k == 0)k = 1;
string buf;
for (int i = 0;i < numRows;++i){
int step = k - i * 2;
if (step == 0)step = k;
int p = i;
while(p < s.size()){
buf += s[p];
p += step;
if (step != k)step = k - step;
}
}
return buf;
}
};