LeetCode——394.字符串解碼

LeetCode——394.字符串解碼

題目

394.字符串解碼
給定一個經過編碼的字符串,返回它解碼後的字符串。
編碼規則爲: k[encoded_string],表示其中方括號內部的 encoded_string 正好重複 k 次。注意 k 保證爲正整數。
你可以認爲輸入字符串總是有效的;輸入字符串中沒有額外的空格,且輸入的方括號總是符合格式要求的。
此外,你可以認爲原始數據不包含數字,所有的數字只表示重複的次數 k ,例如不會出現像 3a 或 2[4] 的輸入。

示例:
s = “3[a]2[bc]”, 返回 “aaabcbc”.
s = “3[a2[c]]”, 返回 “accaccacc”.
s = “2[abc]3[cd]ef”, 返回 “abcabccdcdcdef”.

解析

利用棧的思想,跟編譯原理差不多,注意這種坑 3[a2[c]],第一次是按照第一個例子3[a]2[bc]寫的,寫完才發現還有嵌套的情況,還要注意的是前面的數字可能是多位數,下面直接用的官方題解,我加了詳細的註釋,比較好理解。大致思路就是判斷當前字符①是數字,②是字母或者左括號 [,③是右括號,不同的情況進行對應的處理。這裏用LinkedList來模仿棧,且泛型是String,處理多位數時,直接出一次棧就行,數字入棧前經過了處理,存入的是多位數的String。

代碼

class Solution {
    int ptr; //定義一個下標指針

    public String decodeString(String s) {
        LinkedList<String> stk = new LinkedList<String>(); //LinkedList模仿stack,方便遍歷
        ptr = 0; //下標指針,初始化爲0

        while (ptr < s.length()) {
            char cur = s.charAt(ptr); //獲取下標指針對應的當前字符
            if (Character.isDigit(cur)) { //isDigit() 方法用於判斷指定字符是否爲數字。
                // 獲取一個數(可能是多位數)並進棧
                String digits = getDigits(s); //把所有的數字(可能是多位數)存到digits字符串中
                stk.addLast(digits); //入棧
            } else if (Character.isLetter(cur) || cur == '[') {
                // 左括號或者字母則進棧
                stk.addLast(String.valueOf(s.charAt(ptr++)));
            } else { //這一步說明是右括號],對當前棧內的元素進行處理
                ++ptr;
                LinkedList<String> sub = new LinkedList<String>();
                while (!"[".equals(stk.peekLast())) { //當不是左括號時
                    sub.addLast(stk.removeLast()); //出棧存放到sub中
                }
                Collections.reverse(sub); //sub反轉,因爲出棧的順序是反的
                // 左括號出棧
                stk.removeLast();
                // 此時棧頂爲當前 sub 對應的字符串應該出現的次數
                //注意由於前面對多位數進行了處理,這裏出棧是String類型,所以轉爲整形就直接是多位數了。不是單個字符出棧
                int repTime = Integer.parseInt(stk.removeLast()); //獲取次數

                StringBuffer t = new StringBuffer(); //用來存放構造的字符串
                String o = getString(sub); //獲取sub中的字符串
                // 構造字符串
                while (repTime-- > 0) {
                    t.append(o);
                }
                // 將構造好的字符串入棧
                stk.addLast(t.toString());
            }
        }

        return getString(stk);
    }

    //獲取字符串中的當前位置的數字,拼接成一個新的字符串
    public String getDigits(String s) {
        StringBuffer ret = new StringBuffer();
        while (Character.isDigit(s.charAt(ptr))) { //循環是因爲可能是多位數
            ret.append(s.charAt(ptr++));
        }
        return ret.toString();
    }

    //獲取LinkedList中的字符串
    public String getString(LinkedList<String> v) {
        StringBuffer ret = new StringBuffer();
        for (String s : v) {
            ret.append(s);
        }
        return ret.toString();
    }
}

在這裏插入圖片描述

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