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字符串的规律。
比如s长度为20,rows为5. 每个大间隔为2*rows-2,如果中间有插入值的话,插入2*rows-2-2*i(i为当前行数,0开始计数)。
写时注意几个特例可以加快速度,比如rows比字符串大,或者rows为1时直接返回字符串。
特别注意的是我编程中犯了一个错误,就是把负数和s.size()作比较。
要注意s.size()是size_t型的,unsigned int型的如果用负数做比较那么先会把int转换成size_t,这样负数(最高位为1)永远比s.size()大,最好的方法是先用一个int型存储字符串长度,或者避免负数作比较。
0 8 16
1 7 9 15 17
2 6 10 14 18
3 5 11 13 19
4 12 20
class Solution {
public:
string convert(string s, int numRows) {
int gap = numRows*2-2;
int length = s.size();
string ret;
int index = 0;
if(numRows==1)
return s;
if(length<=numRows)
return s;
for(int i=0; i<numRows; ++i){
index = i;
if(i==0||i==numRows-1){
while(index<length){
ret += s[index];
index += gap;
}
}
else{
while(true){
if((index - 2*i)>=length)
break;
if((index-2*i)>0&&(index-2*i)<length)
ret += s[index-2*i];
if(index<s.size())
ret += s[index];
index += gap;
}
}
}
return ret;
}
};