LeetCode题解——394. 字符串解码

题目相关

题目链接

LeetCode中国,https://leetcode-cn.com/problems/decode-string/。注意需要登录。

题目描述

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

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

题目分析

LeetCode 给出本题难度中等。

题意分析

按照要求对输入字符串进行解码。

样例数据分析

样例数据 1

输入 3[a]2[bc],根据题目意思,我们知道第一个数字 3 表示后面中挎号内的字符串(也就是 a)要重复 3 次。第二个数字 2 表示后面中挎号内的字符串(也就是 bc)要重复 2 次。

因此样例输出 1 的输出为 aaabcbc。

样例数据 2

输入 3[a2[c]],根据题目意思,我们知道第一个数字 3 表示后面中挎号内的字符串(也就是 a2[c])要重复 3 次。第二个数字 2 表示后面中挎号内的字符串(也就是 c)要重复 2 次。

因此我们需要先重复 2[c],得到 cc,然后再重复 3[acc]。得到最后的输出为 accacc。

算法思路

从上面对样例数据 2 的分析中,我们可以发现最好的办法是使用递归。算法的大致描述如下:

1、当前的一个字符进行分析。我们知道这个字符只有两个可能,数字或者字母(题目没说保证小写字母,所以有可能会有大写字母)。

2、如果该字符是数字(使用 isdigit() 判断)。找出从这个位置开始的所有数字,比如 235[a],我们要找到 235。

3、下一位字符必然是 [ 符号,我们要找到最后一个 ]。怎么找?一个个看,如果是 [ 则记号变量加一,如果是 ] 则记号变量减一。

4、这样我们获得数字后面对应 [a[a]b[c]...x] 这个的开始位置和终止位置。然后递归解码从开始位置开始到终止位置结束的子字符串。

5、递归结束后,将找到的子字符串重复上面找到的数字次数。将这个新的字符加入到答案中。

6、如果改字符是字母。将该字符加入到答案中。

看上去确实有些拗口。下面我们可以结合一下代码解释。

AC 参考代码

class Solution {
public:
    string decodeString(string s) {
        string ans;//结果

        //注意 for 循环的第三个参数没有。因为中间要不停修改
        for (int i=0; i<s.length(); ) {
            //解析每一个字符
            if (true==isdigit(s[i])) {
                //数字
                //获取数字
                int val = 0;
                while (true==isdigit(s[i])) {
                    val = val*10+s[i]-'0';
                    i++;
                }

                //定位字母的开始和结束位置
                int j=i+1;
                int sum = 1;//下面至少有一个[
                //确定有几个[],要考虑到3[a2[c]]这样用例
                while (sum>0) {
                    if ('['==s[j]) {
                        sum++;
                    }
                    if (']'==s[j]) {
                        sum--;
                    }
                    j++;
                }

                //递归解决[i, j]内部的字符串
                string ret = decodeString(s.substr(i+1, j-i-2));

                //构造字符串
                while (val--) {
                    ans += ret;
                }

                //更新 i 的位置
                i = j;
            } else {
                //不是数字
                ans += s[i++];
            }
        }

        return ans;
    }
};

假的吧。效率有这么高?我自己都不信。

P.S.

本题可以使用模拟来写,就是利用堆栈。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力的老周

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

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

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

打赏作者

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

抵扣说明:

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

余额充值