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 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
分析
这题涉及到ZigZag这个知识点,从题目我们不得而知这是个什么东西,从wiki上,我们可以了解到它大概是这个东西
再看看解释
A zigzag is a pattern made up of small corners at variable angles, though constant within the zigzag, tracing a path between two parallel lines; it can be described as both jagged and fairly regular.
From the point of view of symmetry, a regular zigzag can be generated from a simple motif like a line segment by repeated application of a glide reflection.
The origin of the word is unclear. Its first printed appearance was in French books in the late 17th century.[1]
用我们自己的话讲,就是一个锯齿形的数据模式,本题的要求是将锯齿形的数据(给定行数)复原为原来的数据。这题着重考察的是数学关系的发现,我们采取的策略是从锯齿的最下面那个点开始遍历,给出得函数也是数学关系的一部分,这样我们发现的数学关系如下:
1. 最下面数据的下标是(numRows-1)+[numRows+(numRows-2)]*N.
2. 根据这个数学关系和numRows,我们可以得出每一行字符的排列,就是通过最下面的下标index+i或者index-i得出。
源码
class Solution {
public:
string convert(string s, int numRows) {
string result;
int m = 0;
int math = numRows + (numRows - 2);
vector<vector<char> > v(numRows, vector<char>());
if(numRows == 1||s.size() < numRows) {
return s;
}
for(int i = (numRows-1); i < s.size(); i = i+math) {
for(int j = 0; j < numRows; j++) {
if(j == 0) {
v[j].push_back(s[i]);
} else {
int l = i - j;
int r = i + j;
v[j].push_back(s[l]);
if(j != numRows - 1 &&r < s.size())
v[j].push_back(s[r]);
}
}
m = i;
}
if(m+numRows-1 < s.size()) {
for(int i = 0; i < numRows; i++) {
if(m+numRows-1+i < s.size()) {
v[numRows-1-i].push_back(s[m+numRows-1+i]);
}
}
}
for(int i = numRows-1; i >= 0; i--) {
for(int j = 0; j < v[i].size(); j++) {
result.push_back(v[i][j]);
}
}
return result;
}
};