题解 | #字符串解码-(栈)-(递归)#

字符串解码

http://www.nowcoder.com/practice/4e008fd863bb4681b54fb438bb859b92

描述

题目描述

首先给定我们一个字符串,在这个字符串里面,方括号前面的数字是我们要重复的倍数,方括号里面的字符串是我们要重复,然后让我们输出最后的结果

样例解释

首先我们的样例输入是

"3[3[b]]"

这个我们先从里面的方括号入手,我们先把里面的bb扩大三倍,也就是说我们可以得到bbbbbb

然后我们在从第二层方括号入手我们可以得到bbbbbbbbbbbb bbb bbb

所以最后的输出为

"bbbbbbbbb"

解法一:栈

解题思路

我们很容易发现其实这个题目的难点就是在于我们的括号嵌套,那我们如何处理呢?

我们可以发现我们的括号嵌套都是从最里面的一层开始的,也就是符合我们栈的结构,先进后出,所以我们可以考虑使用栈来求解这个问题

  1. 如果当前当前的数字是数字的话,我们可以存下来,用于后面倍数计算(这里记一下,我们这里的数字都是字符类型的,记得转换为数字类型)
  2. 如果是字符,直接加到我们当前的字符串的末尾
  3. 如果是左括号,直接入栈,看看能有多少个
  4. 如果是右括号,那么我们弹出状态,然后判断

图解代码

20220113155753

20220113155853

20220113155917

20220113160024

20220113160111

20220113160143

20220113160210

代码实现

class Solution {
    string res = "";
    stack<int> num;
    stack<string> alp;
    int multi = 0;
//     res为最后的答案
//     num存储我们的数字
//     alp存储字符
//     multi存储倍数
public:
    string decodeString(string s) {
        for (auto &it : s) {
//             遍历字符串
            if (isdigit(it)) {
//                 判断如果是数字
                multi = multi * 10 + (it - '0');
            } else if (isalpha(it)) {
//                 如果是字母
                res += it;
            } else if (it == '[') {
//                 如果是左括号
                num.push(multi), alp.push(res);
                multi = 0, res = "";
            } else if (it == ']') {
//                 如果是右括号,出栈,然后增添字符串
                string tmp = "";
                int tmp_num = num.top();
                num.pop();
                for (int i = 0; i < tmp_num; i++) tmp += res;
                res = alp.top() + tmp;
                alp.pop();
            }
        }
        return res;
    }
};

时空复杂度分析

时间复杂度: O(n)O(n)

理由如下:nn代表的是字符串的长度,我们遍历整个字符串,并将括号内的进栈和出栈,所以最后的就是O(n)O(n)

空间复杂度: O(n)O(n)

理由如下:维护一个栈的大小,栈的大小与我们的字符串长度有关

解法二:递归

解题思路

其实我们可以发现,我们每次遇到括号其实都是存到栈里,然后我们每一次都是再去找我们的这个括号里面的值,其实我们发现我们每一次的操作都是差不多的,那么这个很符合我们递归的特点,所以我们可以考虑使用递归来解决这个问题

代码实现

class Solution {
    int cnt = 0;
public:
    string dfs(string s, int &cnt) {
        string res = "";
        int num = 0;
        while (cnt < s.size()) {
            if (isdigit(s[cnt])) {
//                 如果是数字直接计算大小
                num = num * 10 + (s[cnt] - '0');
            } else if (s[cnt] == '[') {
//                 是左括号递归处理
                string tmp = dfs(s, ++cnt);
                while (num --> 0) res += tmp;
//                 重复num次
                num = 0;
            } else if (s[cnt] == ']') {
//                 右括号退出
                break;
            } else {
//                 字母直接相加
                res += s[cnt];
            }
            ++cnt;
//             下一位
        }
        return res;
    }
    string decodeString(string s) {
        return dfs(s, cnt);
    }
};

时空复杂度

时间复杂度: O(n)O(n)

理由如下:nn代表的是字符串的长度,我们递归整个字符串,其实也就是把整个字符串跑一边

空间复杂度: O(n)O(n)

理由如下:维护一个递归栈的大小,栈的大小与我们的字符串长度有关,最坏就是整个字符串

机试题目题解 文章被收录于专栏

主要是机试题目的题目讲解和做法

全部评论

相关推荐

秋招进行到现在终于能写总结了。完全没想到战线会拉这么长,过程会如此狼狈,不过更应该怪自己太菜了。好在所有的运气都用在了最后,也是有个去处。背景:双2本硕科班,无竞赛,本科一段研究所实习,硕士一段大厂暑期实习但无转正。技术栈是C++&nbsp;&amp;&nbsp;Golang,实习是客户端音视频(而且是鸿蒙端开发),简历两个C++项目一个Golang项目。主要投递岗位:后端,cpp软开,游戏服务端,测开,以及一些不拘泥于Java的岗位。从8月起总共投递123家公司,笔试数不清了,约面大约30家。offer/oc/意向:友塔游戏(第一个offer,面试体验很好,就是给钱好少南瑞继保(计算机科班点击就送(限男生),不...
乡土丁真真:佬很厉害,羡慕~虽然我还没有到校招的时候,也想讲一下自己的看法:我觉得不是CPP的问题,佬的背书双2,技术栈加了GO,有两段实习。投了123,面了30.拿到11个offer。这个数据已经很耀眼了。这不也是CPP带来的吗?当然也不止是CPP。至少来说在这个方向努力过的也会有好的结果和选择。同等学历和项目选java就会有更好的吗?我个人持疑问态度。当然CPP在方向选择上确实让人头大,但是我觉得能上岸,至于最后做什么方向,在我看来并不重要。至于CPP特殊,有岗位方向的随机性,java不是不挑方向,只是没得选而已。也希望自己以后校招的时候能offer满满
点赞 评论 收藏
分享
评论
4
收藏
分享
牛客网
牛客企业服务