LeetCode ZigZag Conversion(006)解法總結

NewCoder1024發表於2020-03-14

描述

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.

可以看到時間消耗大幅降低。

相關文章