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 RAnd 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的z型,再一行一行读取,输出结果
分析:所谓输出行数为n的z型,是指先沿第一列向下输出n个数,然后沿n*n矩阵的对角线输出下n-2个数,此时位于第n列,再向下输出n个数,以n=4为例,输出如下:
数字为在源字符串中的位置
0 6
1 5 7
2 4 8 ...
3 9
遍历时,按要写入新字符串的顺序遍历,即按上图的每行遍历,共n行;
对于第一行和最后一行,由于没有中间的数,所以这两行相邻列的数相差2n-2,遍历每列即可;
对于其他行,还有中间一列(可看成一列),其值为右侧那一列的值减去当前行数;
最后注意遍历每行的截止条件,即计算出的源字符串下标超出范围,就遍历下一行;
最后要特殊处理n=1时的情况,因为此时2n-2=0,但实际上应取1.
代码:
class Solution {
public:
string convert(string s, int nRows) {
int i=0;
string ans;
ans.resize(s.length(),0);
for(int j=0; j<nRows; j++)
{
int len = nRows*2-2;
if(len==0) len = 1;
for(int k=0; ;k++)
{
int next;
if(k>0 && j>0 && j<nRows-1)
{
next = k*len-j;
if(next>=s.length())
break;
ans[i++] = s[next];
}
next = k*len+j;
if(next>=s.length())
break;
ans[i++] = s[next];
}
}
return ans;
}
};