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)
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".
思路:
举例子:1-20的数字,nRows = 5,输出结果应当为1 9 17 2 8 10 16 18 3 7 11 15 19 4 6 12 14 20 5 13
1 9 17
2 8 10 16 18
3 7 11 15 19
4 6 12 14 20
5 13
对于第一行和最后一行,每个数之间间隔2*nRows - 2
对于中间行而言:
第二行:(1)2,10,18之间仍然间隔2*nRows - 2
(2)2,8之间间隔6,可表示为2*nRows - 2 - 2,同理对于10和16也是
第三行:(1)3,11,19之间间隔2*nRows - 2
(2)3,7之间间隔4,可表示为2*nRows - 2 - 2*2,同理对于11和15也是
第三行:(1)4,12,20之间间隔2*nRows - 2
(2)4,6之间间隔2,可表示为2*nRows - 2 - 2*3,同理对于12和14也是
通过发现以上规律,我们可以得到解题思路:
对于第一行和最后一行,通过简单的循环单独处理,一个个将字符加入到结果集中
对于中间行,每循环一次将每两个字符加入到结果集中,但是要判断字符是否存在越界访问情况
如上面例子第二行2和8,10和16,对于18,其加上间隔2*nRows - 2 - 2*2后字符访问越界
Java代码实现
public class Solution {
public String convert(String s, int nRows) {
if(s == null || s.length() == 0 || nRows <= 1)
return s;
int len = s.length();
//使用StringBuffer运行效率更高
StringBuffer res = new StringBuffer();
//单独处理第一行
for(int i = 0; i < len; i += 2*nRows - 2){
res.append(s.charAt(i));
}
//处理中间行
int k = 1;
for(int i = 1; i < nRows - 1; i++){
for(int j = i; j < len ; j += 2*nRows - 2){
res.append(s.charAt(j));
//判断字符访问是否越界
if((j + 2*nRows - 2 - 2*k) < len){
res.append(s.charAt(j + 2*nRows - 2 - 2*k));
}
}
k++;
}
//单独处理最后一行
for(int i = nRows - 1; i < len; i += 2*nRows - 2){
res.append(s.charAt(i));
}
return res.toString();
}
}