1. 程式人生 > 其它 >劍指Offer 6. Z 字形變換

劍指Offer 6. Z 字形變換

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. 結語

  努力去愛周圍的每一個人,付出,不一定有收穫,但是不付出就一定沒有收穫! 給街頭賣藝的人零錢,不和深夜還在擺攤的小販討價還價。願我的部落格對你有所幫助(*^▽^*)(*^▽^*)!

  如果客官喜歡小生的園子,記得關注小生喲,小生會持續更新(#^.^#)(#^.^#)。