[Chinese ver]
6. ZigZag Conversion
字符串"PAYPALISHIRING"是通過一個如下給定行數的鋸齒模式書寫的:(你可能想要使用一個固定的字體來更好的顯示它)
P A H N
A P L S I I G
Y I R
然後一行一行的讀取這個字符串:“PAHNAPLSIIGYIR”
編寫代碼實現獲取一個字符串然後根據給出的行數來實現這個鋸齒轉換:
string convert(string text, int nRows);
convert(“PAYPALISHIRING”, 3) 應該返回 “PAHNAPLSIIGYIR”.
首先我們來分析下什麼是zigzag pattern,zigzag是鋸齒或之字形的意思。是以一定的角度相交的兩條線依次以其平行線進行重複相交的線路。一開始我以爲是中間都是一行然後旁邊是鋸齒,當爲4行的情況如下(以數字作爲字符的index):
1 7 13
2 8 14
3 6 9 12 15
4 10 16
5 11 17
但是事實並不是這樣的,zigzag pattern 4行的情況應該是如下:
1 7 13
2 6 8 12 14
3 5 9 11 15
4 10 16
字符以這種鋸齒形分佈。
方法一 使用String[]:
public class Solution {
public String convert(String s, int numRows) {
String result = "";
String[] strings = new String[numRows];
for (int i =0;i<numRows;i++){
strings[i] = "";
}
int position = 0 ;
int numRowsIndex = numRows-1;
int step = 1;
//if the numRows is one ,or the s's length is less than numRows ,return s .
if (numRows ==1 || s.length()<numRows){
return s;
}
//loop the every char in the String, when the position is 0,the step is one ,is the position is numRowsIndex,the step is negative one
for (int i =0;i<s.length();i++){
strings[position] += s.charAt(i);
if (position ==0){
step = 1;
}
if (position == numRowsIndex ){
step = -1;
}
position = position+step;
}
for (int i =0;i<numRows;i++){
result += strings[i];
}
return result;
}
}
分析
這個方法將每一行的字符串存入對應的String[i]中,最後在將String[]按順序拼接起來就得到了我們要的結果。當目前的位置在第一行的時候,下一個位置應該向下移動,所以step =1 . 當位置在最後一行的時候,下一個位置應該向上移動,所以step =-1.
時間複雜度 : O(n) 。n是字符串的長度
空間複雜度 : O(n) .
方法二 StringBuilder[]:
public class Solution {
public String convert(String s, int numRows) {
StringBuilder result = new StringBuilder("");
StringBuilder[] strings = new StringBuilder[numRows];
for (int i =0;i<numRows;i++){
strings[i] = new StringBuilder("");
}
int position = 0 ;
int numRowsIndex = numRows-1;
int step = 1;
//if the numRows is one ,or the s's length is less than numRows ,return s .
if (numRows ==1 || s.length()<numRows){
return s;
}
//loop the every char in the String, when the position is 0,the step is one ,is the position is numRowsIndex,the step is negative one
for (int i =0;i<s.length();i++){
strings[position].append(s.charAt(i));
if (position ==0){
step = 1;
}
if (position == numRowsIndex ){
step = -1;
}
position = position+step;
}
for (int i =0;i<numRows;i++){
result.append(strings[i]);
}
return result.toString();
}
}
分析
這個方法原理和方法一一樣,只是把String 換成 StringBuilder來處理,效率有了很大的提高
時間複雜度 : O(n) 。n是字符串的長度
空間複雜度 : O(n) .
方法三 間隔算法
public class Solution {
public String convert(String s, int numRows) {
String result="";
if(numRows==1)
return s;
int step1,step2;
int len=s.length();
for(int i=0;i<numRows;++i){
step1=(numRows-i-1)*2;
step2=(i)*2;
int pos=i;
if(pos<len)
result+=s.charAt(pos);
while(true){
pos+=step1;
if(pos>=len)
break;
if(step1>0)
result+=s.charAt(pos);
pos+=step2;
if(pos>=len)
break;
if(step2>0)
result+=s.charAt(pos);
}
}
return result;
}
}
分析
/*n=numRows
Δ=2n-2 1 2n-1 4n-3
Δ= 2 2n-2 2n 4n-4 4n-2
Δ= 3 2n-3 2n+1 4n-5 .
Δ= . . . . .
Δ= . n+2 . 3n .
Δ= n-1 n+1 3n-3 3n-1 5n-5
Δ=2n-2 n 3n-2 5n-4
*/
這個方法主要是通過間隔的規律來進行計算和排位。
時間複雜度 : O(n) 。n是字符串長度
空間複雜度 : O(n) .
如果你有更好的辦法或者對我這裏的描述有其他看法,請聯繫我。謝謝
About Me
我的博客 leonchen1024.com
我的 GitHub https://github.com/LeonChen1024
微信公衆號