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,这样的效率是非常高的。

 

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