LeetCode刷題記錄 Z字型變換

 下面是我在LeetCode中看到的題目,然後自己寫的解決方法

    /**
     * Z字型變化
     * 原字符串“LEETCODEISHIRING”
     * after-> 
     * L   C   I   R
     * E T O E S I I G
     * E   D   H   N
     * 然後輸出“LCIRETOESIIGEDHN”
     */
    public String convert(String s, int numRows) {
        if(numRows < 2) return s;//小於兩行無法進行變換

        int unitCount = 2 * numRows - 2;//表示一個變換單元中最大的字符量
        
        String[] rows = new String[numRows];//保存轉換格式後每一行的子字符串
        Arrays.fill(rows,"");

        for (int i = 0; i < s.length(); i++) {
            int t;
            if (i+1 <= unitCount){
                t = i + 1;
            } else {
                t = (i + 1) % unitCount;
            }

            t = t == 0 ? unitCount : t;
            
            if(t > numRows){
                t = numRows - (t - numRows);
            }

            rows[t-1] += String.valueOf(s.charAt(i));
        }

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < rows.length; i++) {
            sb.append(rows[i]);
        }

        return sb.toString();   
    }

必須承認我的解題方法寫的比較複雜,也很晦澀。。。主要是新建一個數組,用於保存變換後的每行字符,因此數組的長度就等於Z字變換的numRows。

 

然後這是我在LeetCode上看到有其它大佬寫的,更加簡潔,效率也更高的算法

    public String convert(String s, int numRows) {
        if(numRows < 2) return s;
        List<StringBuilder> rows = new ArrayList<StringBuilder>();
        for(int i = 0; i < numRows; i++) rows.add(new StringBuilder());
        int i = 0, flag = -1;
        for(char c : s.toCharArray()) {
            rows.get(i).append(c);
            if(i == 0 || i == numRows -1) flag = - flag;
            i += flag;
        }
        StringBuilder res = new StringBuilder();
        for(StringBuilder row : rows) res.append(row);
        return res.toString();
    }

    //作者:jyd
    //鏈接:https://leetcode-cn.com/problems/zigzag-conversion/solution/zzi-xing-bian-huan-by-jyd/

這個算法巧妙地利用了flag,以及使用List + StringBuilder代替了數組+String,這樣的效率是非常高的。

 

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