算法-Z字形變換
1、Z字形變換
將一個給定字符串根據給定的行數,以從上往下、從左到右進行 Z 字形排列。
比如輸入字符串爲 "LEETCODEISHIRING" 行數爲 3 時,排列如下:
L C I R
E T O E S I I G
E D H N
之後,你的輸出需要從左往右逐行讀取,產生出一個新的字符串,比如:"LCIRETOESIIGEDHN"。
請你實現這個將字符串進行指定行數變換的函數:
string convert(string s, int numRows);
示例 1:
輸入: s = "LEETCODEISHIRING", numRows = 3
輸出: "LCIRETOESIIGEDHN"
示例 2:
輸入: s = "LEETCODEISHIRING", numRows = 4
輸出: "LDREOEIIECIHNTSG"
解釋:
L D R
E O E I I
E C I H N
T S G
這個題目如果方法想對了就比較簡單,如果想不對,那就很繞了。看到這個題目我們可能首先會想到找規律,不過,找規律並不是一件簡單的事情,可能會帶來很多麻煩。
這就需要我們轉變思路,我們需要一層一層的剝開這個字符串。如果橫着剝開,那就是數學法,找通項公式,如果豎着按列剝開,事情就簡單了很多,我們在按列讀取的時候,可以爲每一行維護一個字符串,讀到哪一行就在後面append字串。
判斷在哪一行append字串的方式也很簡單,我們設置兩個邊界,在增長到或者減小到某個邊界的時候,讀取行的順序進行反轉,不斷地從上到下,再從下到上讀取,直到取完所有字串。
按照上面的描述,我們就可以得到這樣的代碼,寫的比較清晰了,不在多做解釋。
public String convert(String s, int numRows) {
if(s==null||s.length()==0||numRows<=1||s.length()<numRows){
return s;
}
StringBuilder[] sbs=new StringBuilder[numRows];
for(int i=0;i<numRows;i++){
sbs[i]=new StringBuilder();
}
int layer=0;
boolean turn=false;
for(int i=0;i<s.length();i++){
if(!turn){
sbs[layer++].append(s.charAt(i));
}else{
sbs[layer--].append(s.charAt(i));
}
if(layer==-1||layer==numRows){
layer=layer==-1?1:layer-2;
turn=!turn;
}
}
StringBuilder result=new StringBuilder();
for(StringBuilder sb:sbs){
result.append(sb.toString());
}
return result.toString();
}