394. 字符串解码-辅助栈

Posted hequnwang10

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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"

二、解题

辅助栈

将字符串中的字符压入栈,如果不是右括号,则将字符压栈,如果遇到右括号,则出栈,保存[ ]括号中的字符,如果继续出栈是数字,则保存数字N,然后将[ ]复制N次,继续压栈。最后将栈中元素出栈即可。

class Solution 
    public String decodeString(String s) 
        Stack<Character> stack = new Stack<>();
        for(char ch : s.toCharArray())
            if(ch != ']')
                //如果不是右括号 就进栈
                stack.push(ch);
            else
                //如果遇到左括号 就出栈
                //去除[ ]中的字符串
                StringBuilder sb = new StringBuilder();
                //判断栈是否为空 并且 栈的元素是否字符
                while(!stack.isEmpty() && Character.isLetter(stack.peek()))
                    sb.append(stack.pop());
                
                //将字符串翻转
                String substr = sb.reverse().toString();
                //遇到左括号,然后直接将左括号出栈
                stack.pop();

                //判断栈中的字符串是否为数字
                sb = new StringBuilder();
                while(!stack.isEmpty() && Character.isDigit(stack.peek()))
                    //如果为数字
                    sb.append(stack.pop());
                

                int cnt = Integer.valueOf(sb.reverse().toString());
                for(int i = 0;i<cnt;i++)
                    //将字符串拼接cnt次然后压栈
                    for(char subch : substr.toCharArray())
                        stack.push(subch);
                    
                

            
        

        //将栈中的元素出栈
        StringBuilder res = new StringBuilder();
        while(!stack.isEmpty())
            res.append(stack.pop());
        
        return res.reverse().toString();
    


可以优化一下,使用双栈

class Solution 
    public String decodeString(String s) 
        StringBuilder sb = new StringBuilder();
        //保存字符串
        Stack<StringBuilder> strstack = new Stack<>();
        //保存数字
        Stack<Integer> numstack = new Stack<>();
        int sum = 0;
        for(char ch : s.toCharArray())
            //四种情况 1、如果是数字 2、如果是正常的字符串 3、如果是左括号 4、如果是右括号
            //1、如果是数字
            if(Character.isDigit(ch))
                sum = sum * 10 + ch - '0';
            else if(Character.isLetter(ch))
                //2、如果是正常的字符串 
                sb.append(ch);
            else if(ch == '[')
                //3、如果是左括号
                strstack.push(sb);
                numstack.push(sum);
                //更新
                sb = new StringBuilder();
                sum = 0;
            else
                //4、如果是右括号
                StringBuilder prestr = strstack.pop();
                int cnt = numstack.pop();
                for(int i = 0;i<cnt;i++)
                    prestr.append(sb);
                
                sb = prestr;
            
        
        return sb.toString();
    

其他:

class Solution 
    public String decodeString(String s) 
        //看到需要括号匹配就要想到栈
        StringBuilder res=new StringBuilder();
        int num=0;
        //借助两个栈 用桶型的栈模拟一下就懂了
        LinkedList<String> character=new LinkedList<>();
        LinkedList<Integer> count=new LinkedList<>();
        for (char c:s.toCharArray())
            //只有这四种可能
            if (c=='[')
                count.addLast(num);
                character.addLast(res.toString());
                //清空因为下次还要用
                num=0;
                res=new StringBuilder();
            
            else if (c==']')
                StringBuilder temp=new StringBuilder();
                int num1=count.removeLast();
                for (int i = 0; i < num1; i++) 
                    temp.append(res.toString());

                
                res=new StringBuilder(character.removeLast()+temp);
            
            else if(c<='9'&&c>='0')
                num = num * 10 + c-'0';
            else
                res.append(c);
            
        
        return res.toString();
    

以上是关于394. 字符串解码-辅助栈的主要内容,如果未能解决你的问题,请参考以下文章

394.字符串解码

[JavaScript 刷题] 栈 - 字符串解码, leetcode 394

leedcode 394. 字符串解码(栈,模拟)

[LeetCode]394. 字符串解码(栈)

LeetCode 394. 字符串解码

LeetCode 394. 字符串解码