题目:
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 s, int numRows);
Example 1:
Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"
Example 2:
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P I N
A L S I G
Y A H R
P I
原理:Visit by Row
Intuition
Visit the characters in the same order as reading the Zig-Zag pattern line by line.
Algorithm
Visit all characters in row 0 first, then row 1, then row 2, and so on...
For all whole numbers kk,
- Characters in row 0 are located at indexes k (2⋅numRows−2)
- Characters in row numRows−1 are located at indexes k (2⋅numRows−2)+numRows−1
- Characters in inner row i are located at indexes k (2⋅numRows−2)+i and (k+1)(2⋅numRows−2)−i.
通俗点讲就是 :
1)第 0 行的元素为,行号 row 加上周期的整数倍(cycle = 2 * numRows - 2), 若 j += cycle, 则下标为 row + j,最后一行 numRows -1 ,同理;
2)第1行元素的外侧元素,与第0行元素,有相同规律; 内侧元素的下标为第0 行元素下一个周期的数减去行数row ,若 j += cycle,则 内侧元素下标为 j + cycle - row
class Solution {
public:
string convert(string s, int numRows) {
string res;
int m = s.length();
if(m == 0) return res;
if(numRows == 1) return s;
int cycle = 2*numRows - 2;
for(int row = 0; row < numRows; row++)
{
for(int i = 0; i + row < m; i +=cycle)
{
res.push_back(s[row + i]);
if( row!= 0 && row != numRows - 1 && (i + cycle - row < m))
res.push_back(s[i + cycle - row]);
}
}
return res;
}
};