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"
.
自己的思路,找出规律:i: 判断正负数 :设置一个符号判断 sign,为正则 true,反之 为false ,ii,判断越界 ,如果越界返回0
1.只有一行,原句输出即可
2,只有两行,则奇数偶数分为两行输出
3,>=3行,这个时候找规律,其中第一行和最后一行的间隔都是 j=2*(row-1),第二行 有两种间隔,间隔之和为j,为(j-2)+2,第三行 为j-4)+4;以此类推(不容易实现,规律性差)
别人的思路:
i 对每一行进行处理,再在每一行里把属于此行的数挑出来,追加到string result的后面,注意:string后面可以直接加字符。result+= s[i];
ii.在每一行找数的过程中,行和列下标都从0 开始。
奇数列情况:当前数索引值=前一个数+2*(row-i-1) 其中i为行下标
偶数列情况:当前数索引值=前一个数+2*(row-1)
源代码:
class Solution {
public:
string convert(string s, int nRows) {
int l=s.length();
string r;// store the result
if(nRows==1||l==0)
return s;
for(int row=0;row<nRows&&row<l;row++){ //需要想到 行数大于字符数的情况,如:aa,nRows=5;
r+=s[row];
int index=row;
for(int k=1;k<l;k++){ //用作每行扫描,其实是列数
if(row==0||row==nRows-1){
index+=2*(nRows-1);
}
else{
if(k&0x1)//奇数
index+=2*(nRows-row-1);
else
index+=2*(row);
}
if(index<l)
r+=s[index];
else break;
}
}
return r;
}
};
另一种简易方法:利用竖排和斜排的规律,定义字符串数组,并掐头去尾,把中间斜线部分从下往上(和前一竖排连续)表示出来
class Solution {
public:
string convert(string s, int nRows) {
int len=s.length();
string result[nRows];//字符串数组,每一行是一个字符串,
int i=0;
int gap=nRows-2;//斜线存入
if(nRows==1||len==0)
return s;
while(i<len){
for(int j=0;i<len&&j<len&&j<nRows;j++)
result[j]+=s[i++];
for(int k=gap;i<len&&k>0;k--)//k最大为行数减去2,最小为1,行数最小下标为0
result[k]+=s[i++];
}
string r="";
for(i=0;i<nRows;i++)
r+=result[i];
return r;
}
};