字符串解码

字符串解码

​ 题目描述

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

编码规则为: 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".

1:辅助栈

这个题可以先参考下leetcode的第20题:有效的括号。使用的都是辅助栈操作。

  1. 解码顺序问题,对于非嵌套括号的可以按顺序来进行解码;当出现嵌套括号时,一般情况是先对内层的括号进行解码
  2. 如何去判断内层括号与外层的括号。利用栈来判断第一个]出现的时候,说明内层的括号关闭了,这时候应该解码出内层括号里面的内容
  3. 在遍历的过程中
    • 字符为数字,解析数字(注意连续数字的情况)存入num
    • 字符为[,把之前得到的数字 num和 字母str分别压栈,然后把数字重置为0,字母字符串重置为空串
    • 字符为字母,拼接字母 存入str
    • 字符为],,数字栈栈顶数字出栈,作为重复次数 n,字母栈栈顶字母出栈,作为前缀字母字符串去拼接str字母变量,总共拼接 n 次,拼接后的新字母串给str
/**
 * 例如:
 * 2[abc]3[cd]ef
 *  ↑
 * 遇到左括号,把数字 num=2 和 字母 str="" 入栈,并且 num 和 str 重置
 *    |   |      |    |
 *    |   |      |    |
 *    |_2_|      |_""_|
 *   numStack    strStack
 *
 * 2[abc]3[cd]ef
 *      ↑
 * 遇到左括号,num=0 str="abc",numStack 和 strStack 栈顶元素出栈 str = strStack.pop() + str \* numStack.pop() = "" + "abc" * 2 =  "abcabc"
 *    |   |      |   |
 *    |   |      |   |
 *    |___|      |___|
 *   numStack    strStack
 *
 * 2[abc]3[cd]ef
 *        ↑
 * 遇到右括号,数字 num=3 和 字母 str="abcabc" 入栈,并且 num 和 str 重置
 *    |   |      |        |
 *    |   |      |        |
 *    |_3_|      |_abcabc_|
 *   numStack    strStack
 *
 * 2[abc]3[cd]ef
 *           ↑
 * 遇到左括号,num=0 str=cd,numStack 和 strStack 栈顶元素出栈 str = "abcabc" + "cd" * 3 = "abcabccdcdcd"
 *    |   |      |        |
 *    |   |      |        |
 *    |_3_|      |_abcabc_|
 *   numStack    strStack
 *
 * 遍历结束,最终结果 str="abcabccdcdcdef"
 */
class Solution {
    public String decodeString(String s) {
        // 两个辅助栈,一个用来存放数字,另外一个用来存放字符串
        LinkedList<String> strStack = new LinkedList<>();
        LinkedList<Integer> numStack = new LinkedList<>();
        int index = 0;
        int len = s.length();
        int num = 0;
        StringBuilder str = new StringBuilder();
        while(index < len) {
            char tmp = s.charAt(index);
            // 数字,转换类型char->int
            if(Character.isDigit(tmp)) {
                num = num * 10 + tmp - '0';
            } else if(	
                // 字符
Character.isLowerCase(tmp) || Character.isUpperCase(tmp)) {
                str.append(tmp);
            } else if(tmp=='[') {
                // 入栈
                strStack.push(str.toString());
                numStack.push(num);
                str = new StringBuilder();
                num = 0;
            } else {
                // 出栈
                StringBuilder preSB = new StringBuilder().append(strStack.pop());
                int times = numStack.pop();
                for (int j = 0; j < times; j++) {
                    preSB.append(str);
                }
                str = preSB;
            }
            index++;
        }
        return str.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值