leetcode 394. Decode String(解码字符串)

本文介绍了解码特定格式编码字符串的算法实现,通过使用两个栈分别存放数字和字符串,有效地处理了重复子串的问题。示例代码展示了如何解析如'3[a2[c]]'的输入,正确返回'accaccacc'。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given an encoded string, return its decoded string.

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer.

You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.

Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won’t be input like 3a or 2[4].

Examples:

s = “3[a]2[bc]”, return “aaabcbc”.
s = “3[a2[c]]”, return “accaccacc”.
s = “2[abc]3[cd]ef”, return “abcabccdcdcdef”.

k[encoded_string]表示把encode_string重复k次,原字符串中不含数字

思路:
有括号匹配问题所以用Stack,用两个Stack,一个用来放数字,一个用来放字符串,
当遇到" [ “时,push入数字和之前的字符串,push之后要把之前保存数字和字符串的临时变量清空,遇到连续数字时要记得用十进制法相加。
遇到” ] "时,从两个Stack中分别pop出数字和字符串,把字符串复制k次

注意遇到" [ “时,数字是” [ “之前的数字,而对应的字符串是在” [ “后面的,也就是数字对应的字符串是保存在临时变量中的
比如s = “3[a2[c]]”, 遇到第一个” [ “,数字Stack中push进3,但是string的Stack是”",遇到第二个" [ “时,数字Stack中再push进2,string的Stack中push进之前的“a”
遇到第一个” ] “时,c是保存在tmp变量中的,因为“c”后面没有” [ “,所以“c“没有进Stack,这时要把tmp的”c“复制2次,再从Stack中pop出a,把复制好的”cc“接在”a后面,把“acc”保存进tmp变量,这样在下一步遇到” ] "时仍可以重复这个操作。

为节省临时字符串变量tmpStr的Object建立,用StringBuilder

    public String decodeString(String s) {
        if(s == null || s.length() == 0) {
            return s;
        }
        
        Stack<Integer> stNum = new Stack<>();
        Stack<String> stStr = new Stack<>();
        StringBuilder tmpStr = new StringBuilder();
        int cnt = 0;
        
        String result = "";
        
        for(int i = 0; i < s.length(); i++) {
            if(s.charAt(i) >= '0' && s.charAt(i) <= '9') {
                cnt = cnt * 10 + s.charAt(i) - '0';
            } else if(s.charAt(i) == '[') {
                stNum.push(cnt);
                stStr.push(tmpStr.toString());
                cnt = 0;
                tmpStr.delete(0, tmpStr.length());
            } else if(s.charAt(i) == ']') {
                result = stStr.pop();
                int end = 1;
                if(stNum.peek() != null) {
                    end = stNum.pop();
                }
                for(int k = 0; k < end; k++) {
                    result += tmpStr.toString();
                }
                tmpStr.delete(0, tmpStr.length());
                tmpStr.append(result);
            } else {
                tmpStr.append(s.charAt(i));
            }
        }
                
        return tmpStr.toString();
    }

下面这样写更易懂,但是运行时间比上面的版本长

    public String decodeString(String s) {
        if(s == null || s.length() == 0) {
            return s;
        }
        
        Stack<Integer> stNum = new Stack<>();
        Stack<String> stStr = new Stack<>();
        String tmpStr = "";
        int cnt = 0;
        
        String result = "";
        
        for(int i = 0; i < s.length(); i++) {
            if(s.charAt(i) >= '0' && s.charAt(i) <= '9') {
                cnt = cnt * 10 + s.charAt(i) - '0';
            } else if(s.charAt(i) == '[') {
                stNum.push(cnt);
                stStr.push(tmpStr);
                cnt = 0;
                tmpStr = "";
            } else if(s.charAt(i) == ']') {
                result = stStr.pop();
                int end = stNum.pop();
                for(int k = 0; k < end; k++) {
                    result += tmpStr;
                }
                tmpStr = result;
            } else {
                tmpStr += s.charAt(i);
            }
        }
              
        return tmpStr;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值