字符串解码 - LeetCode 热题 71

大家好!我是曾续缘💘

今天是《LeetCode 热题 100》系列

发车第 71 天

栈第 3 题

❤️点赞 👍 收藏 ⭐再看,养成习惯

字符串解码

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

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

提示:

  • 1 <= s.length <= 30
  • s 由小写英文字母、数字和方括号 '[]' 组成
  • s 保证是一个 有效 的输入。
  • s 中所有整数的取值范围为 [1, 300] 
难度:💖💖

解题方法

给定的字符串是一段已经按照某种规则编码过的文本,我们的任务是解析这段文本,得到解码后的字符串。

这个问题可以用栈来解决。我们遍历给定的编码字符串,根据不同的字符类型,将它们放入栈中。

  1. 当遇到数字时,我们把数字作为重复次数放入栈中。
  2. 当遇到字母或左括号时,我们把字母或左括号作为字符放入栈中。
  3. 当遇到右括号时,说明一个编码单元结束了,我们需要解析这个编码单元。我们先从栈中弹出字符串,翻转弹出的字符串,再弹出重复次数,将字符串重复对应的次数,然后把结果重新放入栈中。

这样,我们遍历完整个字符串后,栈中就只剩下了解码后的字符串。

Code

class Solution {
    public String decodeString(String s) {
        // 创建一个链表形式的栈,用于存储字符串、数字和临时字符串
        LinkedList<String> stk = new LinkedList<String>();
        int i = 0;
        while(i < s.length()){
            char cur = s.charAt(i);
            if(Character.isDigit(cur)){
                // 遇到数字,构建一个数字字符串
                StringBuilder digit = new StringBuilder();
                while (Character.isDigit(s.charAt(i))) {
                    digit.append(s.charAt(i++));
                }
                // 把数字字符串放入栈中
                stk.addLast(digit.toString());
            }else if(Character.isLetter(cur) || cur == '['){
                // 遇到字母或左括号,直接把它们放入栈中
                stk.addLast(String.valueOf(s.charAt(i++)));
            }else{
                // 遇到右括号,解析括号内的编码单元
                i++; // 跳过右括号
                LinkedList<String> tmp = new LinkedList<String>();
                while(!"[".equals(stk.peekLast())){
                    tmp.addLast(stk.removeLast()); // 弹出栈中的字符,直到遇到左括号
                }
                // 翻转括号内的编码单元
                Collections.reverse(tmp);
                // 弹出左括号
                stk.removeLast();
                // 弹出栈中的重复次数
                int repeat = Integer.parseInt(stk.removeLast());
                // 构建一个临时字符串,用于存放重复的字符串
                StringBuilder sb = new StringBuilder();
                StringBuilder one = new StringBuilder();
                for (String t : tmp) {
                    one.append(t);
                }
                // 将字符串重复对应的次数,并放入栈中
                while(repeat-- > 0){
                    sb.append(one);
                }
                stk.addLast(sb.toString());
            }
        }
        // 栈中剩下的就是解码后的字符串
        StringBuilder ans = new StringBuilder();
        for (String t : stk) {
            ans.append(t);
        }
        return ans.toString();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值