LeetCode ZigZag Conversion(006)解法总结

337 阅读2分钟

描述

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

思路

其实对这个z字型的排列,可以看做一个压栈和弹栈的过程(字符的行数),使用count进行计数,碰到栈顶和栈底切换压栈和弹栈操作即可。

要注意行数为1的特殊情况。

class Solution {
    public String convert(String s, int numRows) {
        if(numRows == 1 || numRows == 0){
            return s;
        }

        //创建StringBuffer接收调整过顺序的字符
        StringBuffer out = new StringBuffer();

        //为每行字符进行一次遍历
        for(int i = 0;i<numRows;i++){
            boolean flag = true;
            int count = 0;
            for(int j = 0;j<s.length();j++){
                //当count等于行数时说明这个字符是这行的
                if(count == i){
                    out.append(s.charAt(j));
                }
                
                if(count == numRows -1){
                    flag = false;
                }else if(count == 0){
                    flag = true;
                }
                if(flag){
                    count++;
                }else{
                    count--;
                }
            } 
        }
        
        //输出
        return out.toString();
    }
}
Runtime: 52 ms, faster than 8.89 % of Java online submissions for ZigZag Conversion.
Memory Usage: 41.4 MB

可以看到时间消耗较大。

优化

应当积极避免回溯或者多次遍历,所以开辟多个StringBuffer,只需要一次遍历。

class Solution {
    public String convert(String s, int numRows) {
        if(numRows == 1){
            return s;
        }
        
        //为每行都创建一个接收StringBuffer
        StringBuffer out[] = new StringBuffer[numRows];
        //初始化
        for (int i = 0; i < out.length; i++){
            out[i] = new StringBuffer();
        }
        
        boolean flag = true;
        int count = 0;
        for(int j = 0;j<s.length();j++){
            //将以当前count为行号的字符存入对应的StringBuffer
            out[count].append(s.charAt(j));
            
            if(count == numRows -1){
                flag = false;
            }else if(count == 0){
                flag = true;
            }
            
            if(flag){
                count++;
            }else{
                count--;
            }
        } 
        
        //全部合并到第一个StringBuffer
        for(int i = 1;i<out.length;i++){
            out[0].append(out[i]);
        }

        //输出
        return out[0].toString();
    }
}
Runtime: 6 ms, faster than 61.23% of Java online submissions for ZigZag Conversion.
Memory Usage: 41.8 MB, less than 17.02% of Java online submissions for ZigZag Conversion.

可以看到时间消耗大幅降低。