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 RAnd 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字符串的排列顺序如下:
0 8 16
1 7 9 15 17
2 6 10 14 18
3 5 11 13
4 12
通过下标可以找到规律,对于第一行和最后一行输出,每个元素下标依次递增2*(nRows-1);其他行,设第一个元素为s[i],则每次输出两列(如果都有的话),第一列为i+2*(nRows-i-1),第二列为i+2*(nRows-1),比如s[2]=‘2’,则接下去的元素为2+2*(5-2-1)=6,2+2*(5-1)=10,然后一次循环叠加2*(nRows-1),直到最后一行。
26ms,附上代码:
#include <stdio.h> #include <string> #include <stdlib.h> using namespace std; class Solution { private: string convStr; public: string convert(string s, int nRows) { int i=0, j=0,k=0; int length = s.length(); if (nRows == 1){ return s; } convStr = s; //first row for (i = 0; i < length; i += 2 * (nRows - 1), k++){ convStr[k] = s[i]; } //middle Rows for (i = 1; i < nRows - 1; i++, k++){ convStr[k] = s[i]; j = i; while (j < length){ if (j + 2 * (nRows - i - 1) < length){ k++; convStr[k] = s[j + 2 * (nRows - i - 1)]; } else{ break; } if (j+2*(nRows-1)<length){ k++; convStr[k] = s[j + 2 * (nRows- 1)]; } else{ break; } j += 2 * (nRows - 1); } } //last row; for (i = nRows - 1; i < length; i += 2 * (nRows - 1), k++){ convStr[k] = s[i]; } return convStr; } }; int main(){ Solution solution; printf("%s\n", solution.convert("PAYPALISHIRING", 3).c_str()); system("pause"); return 0; }