6.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

分析:

所謂Z字形即也可說是倒N形,將字符串按下標順序排列成一個個倒N形。思路用numRows個數組來表示每一行該有的元素,最終結果則是遍歷這numRows個數組,而Z字形的規律也很容易找到,可將其分爲兩部分:1.倒N的一豎,翻譯成程序即爲numRows個數組每個都依次(正序)添加一個元素。2.倒N的一瞥,翻譯成程序即爲從numsRows-2到1的數組依次(逆序)添加一個元素。最後程序的終止原字符串遍歷完。然後依次輸出各個數組元素。

代碼:

    public static String convert(String s, int numRows) {
        char[] a = s.toCharArray();
        char[][] b = new char[numRows][a.length];
        int [] len = new int[numRows];
        int index=0;
        while(index<a.length) {
        	for(int i=0;i<numRows&&index<a.length;i++) {
        		b[i][len[i]++] = a[index++];
        	}
        	for(int i=numRows-2;i>0&&index<a.length;i--) {
        		b[i][len[i]++] = a[index++];
        	}
        }
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<numRows;i++) {
        	for(int j=0;j<len[i];j++) {
        		sb.append(b[i][j]);
        	}
        }
        return sb.toString();
    }

優化:

採用找規律的方式也能夠很容易找到每一行字符下標的規律。

(1)第一行和第numRows行屬於特殊情況,他們只出現在倒N的一豎上,順序跳躍查找,例如第一行,初始i=0,查找a[i](a爲原字符串s所對應的字符數組),然後i = i + 2 * (numRows - 1);

  (2)  居於第一行和第numRows中間的行,由於他們在倒N的一豎和一瞥上均有元素,一豎上的元素下標遞增方式爲

i + 2 * (numRows - 1),由一豎找到下一個一瞥的方式爲i + 2 * (numsRows - i - 1);

代碼:

	public static String convert1(String s, int numRows) {
		if(numRows==1) {
			return s;
		}
		char[] a = s.toCharArray();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < numRows; i++) {
			int p = i;
			while (p < a.length) {
				sb.append(a[p]);
				if (i != 0 && i != numRows-1 && (p + 2 * (numRows - i - 1))<a.length) {
					sb.append(a[p + 2 * (numRows - i - 1)]);
				}
				p = p + 2 * (numRows - 1);	
			}
		}
		return sb.toString();
	}

注意:上邊(1)中公式i = i + 2 * (numRows - 1),當numRows==1時i不會增加,所以需要在這種算法中判斷numRows==1.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章