劍指Offer 6. Z 字形變換
阿新 • • 發佈:2021-06-25
1. 題目
將一個給定字串 s 根據給定的行數 numRows ,以從上往下、從左到右進行Z 字形排列。比如輸入字串為 "PAYPALISHIRING"行數為 3 時,排列如下:
P A H N
A P L S I I G
Y I R
之後,你的輸出需要從左往右逐行讀取,產生出一個新的字串,比如:"PAHNAPLSIIGYIR"
。
請你實現這個將字串進行指定行數變換的函式:
string convert(string s, int numRows);
2. 示例
示例1:
輸入:s = "PAYPALISHIRING", numRows = 3 輸出:"PAHNAPLSIIGYIR"
示例2:
輸入:s = "PAYPALISHIRING", numRows = 4
輸出:"PINALSIGYAHRPI"
解釋:
P I N
A L S I G
Y A H R
P I
示例3:
輸入:s = "A", numRows = 1
輸出:"A"
提示:
1 <= s.length <= 1000
s 由英文字母(小寫和大寫)、',' 和 '.' 組成
1 <= numRows <= 1000
3. 題解
這個題目存在潛在規律,我們只要把index和行號的關係找到就能按照一定順序輸出字串了。
首先我們觀察第一行,第j列第一個數和第j+1列第一個數之間,第j列第一個數所在列下面有numRows - 1個數,-1就是第一個數;第在斜對角線上,除去第j列最後一個元素,剩下numRows-1;總的數為(numRows-1) + (numRows-1) = 2 * numRows - 2。所以第一行的index為:i + k * (2 * numRows -2), i = 0。
觀察第i行(0<i<numRows-1),發現除了有與第一行同樣的規律,即i+ k * (2 * numRows - 2);中間還有一個數,它離第i行第j+1列數中間隔了2i個數,即i + k*(2*n - 2) - 2i = k*(2*numRows - 2) - i;
最後一行與第一行一樣的。
4. 實現
public class Convert6 {
public String convert(String s, int numRows) {
if(numRows == 1) return s;
StringBuilder str = new StringBuilder();
int n = s.length();
int cycleLen = 2 * numRows - 2;
for(int i = 0; i < numRows; i++) {
for(int j = 0; j + i < n; j += cycleLen) {
str.append(s.charAt(j + i));
if(i != 0 && i != numRows - 1 && j + cycleLen - i < n) {
str.append(s.charAt(j + cycleLen - i));
}
}
}
return str.toString();
}
public static void main(String[] args) {
String str = "PAYPALISHIRING";
int numRows = 3;
System.out.println(new Convert6().convert(str, numRows));
}
}
5. 結語
努力去愛周圍的每一個人,付出,不一定有收穫,但是不付出就一定沒有收穫! 給街頭賣藝的人零錢,不和深夜還在擺攤的小販討價還價。願我的部落格對你有所幫助(*^▽^*)(*^▽^*)!
如果客官喜歡小生的園子,記得關注小生喲,小生會持續更新(#^.^#)(#^.^#)。