1. 程式人生 > >【leecode】 6.ZigZag Conversion(鋸齒形變換)

【leecode】 6.ZigZag Conversion(鋸齒形變換)

  • The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

P A H N A P L S I I G Y I R

  • And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string s, int numRows);

Example 1:

Input: s = “PAYPALISHIRING”, numRows = 3 Output: “PAHNAPLSIIGYIR”

Example 2:

Input: s = “PAYPALISHIRING”, numRows = 4 Output: “PINALSIGYAHRPI” Explanation: P I N A L S I G Y A H R P I

解法一:用二維陣列存放矩陣字元,遍歷字串,按照要求選擇位置存放字元。

//該演算法考慮的太多了,超時
    public  static String convert(String s, int numRows) {
        if (numRows==1) return s;//一行的情況
        if (s.length()<=numRows) return s;//
        int[][] a = new int[numRows][((s.length()/(2*numRows-2)+1)*(numRows))];//定義二維陣列用來儲存字元,最後在輸出字元
        int i=0; //i在這裡控制字串的索引。
        String str = "";
        for (int m=0;m<a[0].length;m++){
            for (int n=0;n<a.length;n++){
                if (numRows==2)//兩行的情況
                    if (m%2==1&n!=1){
                        if (i==s.length()){ break;}
                        a[n][m] = s.charAt(i);
                        i=i+1;
                    }else {
                        if (i == s.length()) { break; }
                        a[n][m] = s.charAt(i);
                        i = i + 1;
                    }
                if (numRows>2&&m%(numRows-1)!=0&& n == (numRows-m%(numRows-1)-1)){//m%(numRows-1)是篩選出有空的列, n == (numRows-m%(numRows-1)-1)是篩選出
                        if (i==s.length()){ break;}
                        a[numRows-m%(numRows-1)-1][m] = s.charAt(i);
                        i=i+1;
                }else if (numRows>2&&m%(numRows-1)==0){
                    if (i==s.length()){ break;}
                    a[n][m] = s.charAt(i);
                    i=i+1;
                }
            }
        }
        for (int k = 0;k<a.length;k++){
            for (int p =0;p<a[0].length;p++){
                    str += (char) a[k][p];
            }
        }
        return str.replace("\u0000","");
    }

解法二:根據規則,判斷出是【行數減一】的圖形成倍擴充套件,且整除【行數減一】的全部都排列字元,其他的列排一個,且按照遞減的順序,所以可以設定一個標誌位flag,用來操作遞減,從0-numrows或者從numrows-0,不斷的迭代。

  public static String convert2(String s,int numRows){
        if (numRows==1) return s;
        List<StringBuilder> rows = new ArrayList<>();
        //給rows構造幾行,如果字串長度小於給定的長度,按照字串的長度來定義
        for (int i =0;i<Math.min(s.length(),numRows);i++){ rows.add(new StringBuilder()); }
        int row = 0;
        Boolean flag = false;
        for (char c : s.toCharArray()){
            rows.get(row).append(c);
            //判斷依據是第一行和最後一行,其它有空白列是根據全滿的一列
            if(row==0||row==numRows-1) flag = !flag;
            row += flag ? 1 : -1;
        }
        //賦值完成,開始遍歷
        StringBuilder res =  new StringBuilder();
        for (StringBuilder l : rows){
            res.append(l);
        }
        return res.toString();
    }