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", "");
}