LeetCode 算法:字符串解码 c++

原题链接🔗字符串解码
难度:中等⭐️⭐️

题目

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

编码规则为: 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. 解题思路:

LeetCode上的"字符串解码"问题通常指的是给定一个由数字和字母组成的字符串,其中数字表示前面字符的重复次数。问题要求解码这个字符串,得到不含数字的原始字符串。

例如,对于字符串 "3[a2[bc]d]",解码后的字符串是 "addbc"

这个问题可以通过使用栈(Stack)数据结构来解决。以下是解决这个问题的一种思路:

  1. 初始化:创建一个空栈,用于存储解码过程中的字符。

  2. 遍历字符串:从左到右遍历输入字符串的每个字符。

  3. 处理字母:如果当前字符是字母,直接入栈。

  4. 处理数字

    • 当遇到数字时,记录当前数字,并继续读取下一个字符,直到遇到非数字字符(即字母或栈底)。
    • 将记录的数字作为重复次数,存储在变量中。
  5. 处理重复

    • 当完成一个数字的记录并且遇到非数字字符时,检查栈顶是否有字符。
    • 如果有,将栈顶字符复制数字指定的次数,并将这些复制的字符再次入栈。
  6. 处理嵌套

    • 如果当前字符是左括号 [,则将当前栈深度加一,并入栈。
    • 如果当前字符是右括号 ],则说明遇到了一个嵌套的结束。将栈中字符一直弹出,直到遇到左括号 [,并将左括号也弹出。这个过程中,每弹出一个字符,都要根据当前的数字重复次数进行复制操作。
  7. 构建结果:当遍历完整个字符串后,栈中剩余的字符就是解码后的字符串。

  8. 返回结果:将栈中剩余的字符弹出并拼接成字符串,作为最终结果返回。

  1. c++ demo:
#include <iostream>
#include <string>
#include <stack>

using namespace std;

class Solution {
public:
    string src;
    size_t ptr;

    int getDigits() {
        int ret = 0;
        while (ptr < src.size() && isdigit(src[ptr])) {
            ret = ret * 10 + src[ptr++] - '0';
        }
        return ret;
    }

    string getString() {
        if (ptr == src.size() || src[ptr] == ']') {
            // String -> EPS
            return "";
        }

        char cur = src[ptr]; int repTime = 1;
        string ret;

        if (isdigit(cur)) {
            // String -> Digits [ String ] String
            // 解析 Digits
            repTime = getDigits();
            // 过滤左括号
            ++ptr;
            // 解析 String
            string str = getString();
            // 过滤右括号
            ++ptr;
            // 构造字符串
            while (repTime--) ret += str;
        }
        else if (isalpha(cur)) {
            // String -> Char String
            // 解析 Char
            ret = string(1, src[ptr++]);
        }

        return ret + getString();
    }

    string decodeString(string s) {
        src = s;
        ptr = 0;
        return getString();
    }
};


int main() {
    Solution solution;
    string input = "3[a2[c]]";
    cout << "Decoded string: " << solution.decodeString(input) << endl;
    return 0;
}
  • 输出结果:

Decoded string: accaccacc

  1. 代码仓库地址decodeString
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的出现位置。它的时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度。 KMP算法的核心思想是利用已知信息来避免不必要的字符比较。具体来说,它维护一个next数组,其中next[i]表示当第i个字符匹配失败时,下一次匹配应该从模式串的第next[i]个字符开始。 我们可以通过一个简单的例子来理解KMP算法的思想。假设文本串为S="ababababca",模式串为P="abababca",我们想要在S中查找P的出现位置。 首先,我们可以将P的每个前缀和后缀进行比较,得到next数组: | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | --- | - | - | - | - | - | - | - | - | | P | a | b | a | b | a | b | c | a | | next| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 接下来,我们从S的第一个字符开始匹配P。当S的第七个字符和P的第七个字符匹配失败时,我们可以利用next[6]=4,将P向右移动4个字符,使得P的第五个字符与S的第七个字符对齐。此时,我们可以发现P的前五个字符和S的前五个字符已经匹配成功了。因此,我们可以继续从S的第六个字符开始匹配P。 当S的第十个字符和P的第八个字符匹配失败时,我们可以利用next[7]=1,将P向右移动一个字符,使得P的第一个字符和S的第十个字符对齐。此时,我们可以发现P的前一个字符和S的第十个字符已经匹配成功了。因此,我们可以继续从S的第十一个字符开始匹配P。 最终,我们可以发现P出现在S的第二个位置。 下面是KMP算法C++代码实现:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Codec Conductor

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

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

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

打赏作者

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

抵扣说明:

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

余额充值