LeetCode 6. 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”.
题目描述:
给定一个字符串,按照参数的的行数,进行之字形走位排列,返回走位的按行读取的内容。比如给定的字符串是”PAYPALISHIRING”,首先排列第一列,为P,A,Y,然后进行之字形,第二列第二行为P。
解析:
方法1:
题目的意思是把字符串上下上下走之字形状,然后按行输出,比如包含数字0~22的字符串, 给定行数为5,走之字形如下:

现在要按行输出字符,即:0 8 16 1 7 9 15 17 2…….
如果把以上的数字字符看做是字符在原数组的下标, 给定行数为n = 5, 可以发现以下规律:
(1)第一行和最后一行每个元素下标间隔都是interval = n*2-2 = 8 ; 如0,8,16等
(2)中间行的间隔是周期性的,第i行的间隔是: interval–2*i, 2*i, interval–2*i, 2*i, interval–2*i, 2*i, …
根据以上规律,给出如下代码:
[cc lang=”C++”]
class Solution {
public:
string convert(string s, int numRows) {
string result = “”;
int len = s.length();
if(len <= 1)
return s;
for (int i = 0; i < numRows; ++i)
{
for (int j = i;j < len;j += 2 * (numRows - 1))
{
result.push_back(s[j]);
if (i > 0 && i < numRows - 1)
{
if (j + 2 * (numRows - i - 1) < len)
result.push_back(s[j + 2 * (numRows - i - 1)]);
}
}
}
return result;
}
};
[/cc]
结果正确,但是实际在LeetCode中会超时。
对代码进行优化:
[cc lang="C++"]
string convert(string s, int nRows) {
if(nRows <= 1) return s;
string result = "";
//the size of a cycle(period)
int cycle = 2 * nRows - 2;
for(int i = 0; i < nRows; ++i)
{
for(int j = i; j < s.length(); j = j + cycle){
result = result + s[j];
int secondJ = (j - i) + cycle - i;
if(i != 0 && i != nRows-1 && secondJ < s.length())
result = result + s[secondJ];
}
}
return result;
}
[/cc]