[Leetcode] 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)
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".
题意:给定的一个文本串是以Z字形遍历nRows行字符串的得到的。要返回按行遍历的结果,先理解遍历方式,结合题中给出的例子说明:
1)nRows=2时,遍历的方式为:
返回的结果是:PYAIHRN APLSIIG;(实际返回时没有空格,这里只是为看的方便,如下)
2)nRows=3时,遍历的方式为:
返回的结果是:PAHN APLSIIG YIR;
3)nRows=4时,遍历的方式为:
从上三种排布的情况,可以知道,针对首、尾两行,相邻元素之间的下标之差和行数有关,为:2*nRows-2 ;针对中间的行数,每行中,竖列和相邻斜着的部分(如nRows=4时,黑框所示),下标之差满足 j+2*nRows-2-2*i ,其中 j 为当前点,(同行)前一点的下标,i 为行数。而同行中,两竖列字符下标之差依旧为 2**nRows-2 。所以整个程序,只要单独表示出同行中竖列和相邻斜着字符的下标之间的关系即可,剩下的每次都是间隔 2*nRows-2 相加即可。如,当nRows=4时,整个程序的遍历到第二行,即 i=1 ,先res+s[ j]=res+A;然后通过 1+6-2=5求得下一字符为L,res+AL,进入下一循环,这样就遍历到下标为1+6=7的字符,res+ALS,这样通过7+6=13得到G,所以遍历第二行以后,结果为res+ALSIG,然后继续遍历下一层,代码如下:
class Solution { public: string convert(string s, int nRows) { if(nRows<=1) return s; string res=""; int space=2*nRows-2; for(int i=0;i<nRows;++i) { for(int j=i;j<s.size();j+=space) { res+=s[j]; int temp=j+space-2*i; if(i !=0&&i !=nRows-1 &&temp<s.size()) res+=s[temp]; } } return res; } };