[leetcode 6] ZigZag Conversion

来源:互联网 发布:java分类 编辑:程序博客网 时间:2024/04/29 16:47

题目:

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   NA P L S I I GY   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".

思路:

1.本题旨在按照字符串绘制一个类似于Z字形的折线,然后按行重现构造字符串;
2.构造形式如下图所示:

3.在图中,nRows为6(即表格上下共有6条线,每条代表1行),每个表格中数据代表其左上角所存字符在原字符串中位置;
4.按照题意,结果将按照0-10-20-1-9-11-19-21-2-8-12-28-22···的顺序重新构造;
5.由于行数给定(如6),那么我们可以考虑按照行数遍历得出新的字符串;
6.观察图得知:在第0行(及最后一行)中,两个点之间的差为10,原因在于,此值为0点下的点个数与10一下的点个数之和,在第0行下共有nRows-1行,除最后一行外每行有两个点,计算10=2*(nRows-1)-1+1,那么除外后一行外,设此时为第i行,若观察点此时在偶数列(如点1),则下一点(9)到该点的距离为2*(nRows-i-1)-1+1,若观察点在奇数列(点9),下一点至改点距离为(2*(nRows-1)-1+1)-(2*(nRows-i-1)-1+1);
7.在6中计算出了在任意一行两点之间距离的计算公式,依照这些公式,就可以按行遍历,得出每一行的字符串,然后将这些字符串拼接,即可得出最后的字符串;
8.其实本题思路为两层遍历,先按行遍历,在每一行中再按列遍历,但是由于本题获取列数并不方便,所以只要时刻保证当前下标小与原始字符串即可,这样可以作为列遍历的限制;
9:本算法对字符串仅遍历一次,故时间复杂度为O(n);

代码:

class Solution{public:string convert(string s, int nRows){int len=s.length();if(len==0 || nRows<=1)    return s;string result="";for(int i=0;i!=nRows && i!=len;++i){result+=s[i];int step=0;int idx=i;for(int c=0;idx<len;++c){if(i==0 || i==nRows-1)step=2*(nRows-1);else{if(!(c%2))step=2*(nRows-1-i);elsestep=2*(nRows-1)-2*(nRows-1-i);}idx+=step;if(idx<len){result+=s[idx];}}}return result;}};



0 0
原创粉丝点击