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"
.
思路很渣,先建立一个矩阵,然后将给的字符串按照ZIGZAG输出至矩阵内,再从矩阵内按行列输出(去掉空字符)
class Solution {
public:
string convert(string s, int numRows) {
if (s.length() == 0 || numRows == 1)
{
return s;
}
int fag = 2*numRows -2;
char** flag = new char*[numRows];
int tempClum = (s.length() / (numRows * 2 - 2) + 1 )* (numRows - 1) + 2;
for (int i = 0 ; i < numRows; ++i)
{
flag[i] = new char[tempClum];
for (int k = 0; k < tempClum; ++k)
{
flag[i][k] = '\0';
}
}
//按照ZIGZAG输出至矩阵内
int leng = s.length();
for(int i = 0; i < s.length() / (numRows * 2 - 2) + 1; ++i) //有多少次递归
{
int rows = 0;
int clum = i * (numRows -1);
int j = 0;
for(;j < numRows ; ++j) //第一个处理,从上倒下
{
if (i * (numRows*2 - 2) + j >= s.length())
break;
flag[rows][clum] = s[i * (numRows*2 - 2) + j];
++rows;
}
for (rows = numRows - 2; rows > 0; --rows) //斜线处理
{
if (i * (numRows*2 - 2) + j >= s.length())
break;
clum++;
flag[rows][clum] = s[i * (numRows*2 - 2) + j];
j++;
}
}
//从矩阵中输出
string temp;
for (int i = 0 ; i < numRows; ++i)
{
for (int k = 0; k < tempClum; ++k)
{
if (flag[i][k] != '\0')
{
string temp1;
temp1 = flag[i][k];
temp.append(temp1);
}
}
}
delete []flag;
return temp;
}
};
最主要的思路是要找到ZIGZAG的递归规律,准确的分出每一个递归距离。该题的递归距离是2*rows - 2;
在网上发现一个非常简洁的版本http://blog.csdn.net/cshaxu/article/details/12507201
- class Solution {
- public:
- string convert(string s, int nRows) {
- // Start typing your C/C++ solution below
- // DO NOT write int main() function
- string result;
- if (nRows < 2) return s;
- for (int i = 0;i < nRows;++i) {
- for (int j = i;j < s.length();j += 2 * (nRows - 1)) {
- result.push_back(s[j]);
- if (i > 0 && i < nRows - 1) {
- if (j + 2 * (nRows - i - 1) < s.length())
- result.push_back(s[j + 2 * (nRows - i - 1)]);
- }
- }
- }
- return result;
- }
- };
(1)如果当前给出的行只有1行,那么直接输出
(2)如果当前行是第0行或者是第NROW-1,那么相差为2*NROWS - 2;
(3)如果当前行不是第0行或者是第NROW-1,那么相差为2*NROWS - 2 中间还会穿插一个距离为
2*(NROWS - 2 - i)。