给一个String: "PAYPALISHIRING"
要求按竖Z字方法去排列再横向读出,给定行数R。
若 R = 3:
P A H N
A P L S I I G
Y I R
则程序输出应为 :"PAHNAPLSIIGYIR"
若R = 4 :
P I N
A L S I G
Y A H R
P I
程序输出应为 : "PINALSIGYAHRPI"
分析:找规律,将每行当作一个研究对象,找出每个字母在原字符串中index的代数规律。
找规律最简单的方法就是多举几个例子,其实就是高中数学题中找数组的规律。
本题的规律: /*R=numRows d=2R-2 1 2R-1 4R-3 d= 2 2R-2 2R 4R-4 4R-2 d= 3 2R-3 2R+1 4R-5 . d= . . . . . d= . R+2 . 3R . d= R-1 R+1 3R-3 3R-1 5R-5 d=2R-2 R 3R-2 5R-4 */
假设当前行数是r,总行数R,I(n)表示某行第n个字母在原字符串中的index,n从0开始:
r=1或R时:I(n+1) = I(n)+2*(R-1)
1<r<R时:
I(n+1)=I(n)+2*(R-r),n为偶数
I(n+1)=I(n)+2*(r-1),n为奇数
public static String convert(String s, int numRows) {
if(s == null || s.length() == 0 || numRows ==1 || numRows >= s.length())
return s;
StringBuilder myString = new StringBuilder();
//第1行
for(int i = 1; i < s.length()+1;i+=2*(numRows-1))
myString.append(s.charAt(i-1));
//中间
for(int i = 2; i < numRows;i++) {
boolean k=true;
for(int j = i; j < s.length()+1;j+= (k) ? 2*(numRows-i) : 2*(i-1),k=!k)
myString.append(s.charAt(j-1));
}
//第R行
for(int i = numRows;i<s.length()+1;i+=2*(numRows-1))
myString.append(s.charAt(i-1));
return myString.toString();
}
讨论: 这代码不快(32%),如果用String而不是StringBuilder会更慢大约两倍,
优点在于书写简单逻辑清晰,如果面试碰到,这样的代码应该够了。
若文章中有错误或者各路大神有更好解法,欢迎评论。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。