LeetCode-394. 字符串解码

题目来源

394. 字符串解码

题目详情

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

示例 1:

输入: s = "3[a]2[bc]"
输出: "aaabcbc"

示例 2:

输入: s = "3[a2[c]]"
输出: "accaccacc"

示例 3:

输入: s = "2[abc]3[cd]ef"
输出: "abcabccdcdcdef"

示例 4:

输入: s = "abc3[cd]xyz"
输出: "abccdcdcdxyz"

题解分析

解法一:栈

class Solution {
    public String decodeString(String s) {
        int n = s.length();
        LinkedList<String> sta  = new LinkedList<>();
        int pos = 0;
        while(pos < n){
            char ch = s.charAt(pos);
            if(Character.isDigit(ch)){// 数字直接进栈
                StringBuilder sb = new StringBuilder();
                while(pos < n && Character.isDigit(s.charAt(pos))){
                    sb.append(s.charAt(pos++));
                }
                sta.addLast(sb.toString());
            }else if(Character.isLetter(ch) || ch == '['){// 字母和左括号也进栈
                sta.addLast(String.valueOf(ch));
                pos++;
            }else{// 遇到右括号则出栈直到左括号
                pos++;
                LinkedList<String> list = new LinkedList<>();
                while(!sta.isEmpty() && !sta.peekLast().equals("[")){
                    list.addLast(sta.pollLast());
                }
                sta.pollLast();
                Collections.reverse(list);

                int times = Integer.parseInt(sta.pollLast());
                
                String temp = getStrings(list);
                StringBuilder sb = new StringBuilder();
                for(int i=0; i<times; i++){
                    sb.append(temp);
                }
                sta.addLast(sb.toString());
            }
        } 
        return getStrings(sta);
    }
    
    private String getStrings(List<String> list){
        StringBuilder sb = new StringBuilder();
        for(String str : list){
            sb.append(str);
        }
        return sb.toString();
    }
}

解法二:递归法

class Solution {
    int pos;
    int n;
    String s;
    public String decodeString(String s) {
        n = s.length();
        this.s = s;
        return getString();
    }
    
    private String getString(){
        if(pos == n || s.charAt(pos) == ']'){
            return "";
        }
        String ret = "";
        if(Character.isDigit(s.charAt(pos))){
            
            int times = getDigit();

            pos++;// 跳过左括号

            String temp = getString();// 递归解析括号中间的字符

            pos++;// 跳过右括号

            while(--times >= 0){
                ret += temp;
            }

        }else{
            ret = String.valueOf(s.charAt(pos++));
        }
        return ret + getString();// 继续解析右边的字符
    }

    // 解析数字
    private int getDigit(){
        int ans = 0;
        while(pos < n && s.charAt(pos) != '['){
            ans = ans * 10 + Integer.parseInt(""+s.charAt(pos));
            pos++;
        }
        return ans;
    }
}
posted @ 2021-12-27 11:32  Garrett_Wale  阅读(38)  评论(0编辑  收藏  举报