[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;
    }
};

 

参考博客,爱做饭的小莹子 。还有一种是相邻两行之前分奇偶得出规律的解法,这里仅贴出链接,可以扩展一下思维。

posted @ 2017-06-23 16:45  王大咩的图书馆  阅读(209)  评论(0编辑  收藏  举报