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指的是将字符串组成倒Z的形状,容易发现它的周期为2*n-1(仅指前两条线),在这个周期上用求余的得出行数。
(二刷的时候一定要发现新的方法!)
public String convert(String s, int numRows) {
if(numRows==1){return s;}
if(s==null){return "";}
String[] list = new String[numRows];
int cir = 2*numRows-2,flag = 0;//cir为每n个数一个周期,flag:有多少个中间值
String result = null;
int site = 1,count=1;
if(numRows==2){ //周期要从三行以上才有规律,这是对只有两行的解决方法
for(int i =0;i<s.length();++i){
String c = String.valueOf(s.charAt(i));
if((i+1)%2==0){
list[1] += c;
continue;
}
list[0] += c;
}
for(int j =0;j<list.length;j++){
result += list[j];
}
return result.replaceAll("null", "");
}
for(int i =0;i<s.length();++i){
String c = String.valueOf(s.charAt(i));
if(i+1>cir){
site = i-(flag*cir)+1;
}
if(site<=numRows){//如果计算出的位置比行数小,则放入site-1的数组行里
list[site-1] += c;
site++;
continue;
}
//如果算出的位置值大于行数,计算除这个点的位置:numRows-count-1:行数-1-多少个中间点
list[numRows-count-1]+=c;
//如果中间点数等于行数-2 则完成一个周期,将中间点数设为0
if(count==numRows-2){
count =0 ;
}
count++;
//如果位置数值大于cir 则完成一个周期
if(site==cir){
flag++;
site = 1;
}
site++;
}
for(int j =0;j<list.length;j++){
result += list[j];
}
return result.replaceAll("null", "");
}