题目与解释

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

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a2[4] 的输入。

示例:

s = "3[a![](https://img2018.cnblogs.com/blog/1575923/201903/1575923-20190304151000879-833294601.png)

]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".

解释:

这道实际上是一道字符串与栈结合的问题。如何看出是栈结合的问题呢?

  1. 有匹配('['和']')的情况,需要使用栈来完成匹配过程
  2. 有递归的情况, 如3[2[ab]]这样

在匹配符号上,我参照我之前写的小型计算器的符号匹配,遇到']'就去寻找最近出现的匹配符号'['。

思路

建立一个字符栈,这里用的是STL自带的stack<char>

逐个读入字符压入栈,当遇到']'符号就寻找最近的匹配符号。

这个寻找的过程就是不断判断栈顶是否为'['符号?

->否。这个是括号内的字符,暂时存入一个字符串ss

->是。则寻找到匹配的字符,继续往前寻找'['的字符前的所有"数字字符串",如34[22[ss]],那么22就是[ss]的数字字符串,34则是[22[ss]]的数字字符串。在寻找完后需要将这个字符串转换成实际的数字。

经过一次上述过程后,已经知道一个括号内字符串和这段字符串出现的次数k。我们把k个字符串压入我们创建的字符栈。

而当所有字符都读完了,则转换实际上就已经结束了。我们先根据思路写一段解法,但效率还不是很高。

我们看看"3[a1[b]]"的图例

class Solution {
public:
string decodeString(string s) {
string ans = "";
stack<char>st;
/*visit all the character in the string s*/
for (unsigned i = 0; i < s.length(); i++) {
if (s[i] != ']')st.push(s[i]);
else {
/*
if we find the character ']', it means we find a pair.
string ss means the string in the pair of this times.
string num means the number k in the pair of this times.
Initialize these two strings as an empty string.
*/
string ss = "", num = "";
while (st.top() != '[') {
ss += st.top();
st.pop();
}
/*Delete '[' character*/
st.pop();
/*reverse the string ss*/
reverse(ss.begin(), ss.end());
while (!st.empty() && st.top() <= '9'&&st.top() >= '0') {
num += st.top();
st.pop();
}
unsigned times = 0, index = 1;
for (unsigned i = 0; i < num.length(); i++, index =index* 10) {
times += index * (num[i]-'0');
}
string sss ="";
for (unsigned i = 0; i < times; i++) {
sss += ss;
}
for (unsigned i = 0; i < sss.length(); i++) {
st.push(sss[i]);
}
}
}
/* push the k times string to the stack st*/
while (!st.empty()) {
ans += st.top();
st.pop();
}
reverse(ans.begin(), ans.end());
return ans;
}
};

很暴力的按照思路的过程写了代码,优化点是可以自己写一个stack而不是使用STL的stack,使这个自己写的stack拥有遍历的方法。新增的内容有注释提示。能将上面代码优化4ms。

/*********added below*********/
class Stack {
public:
Stack() {
topNum = -1;
ll.clear();
}
void push(char c) {
ll.push_back(c);
topNum++;
}
char top() {
return ll[topNum];
}
void pop() {
ll.pop_back();
topNum--;
}
bool empty() {
return topNum == -1;
}
vector<char>ll;
private:
int topNum;
};
/******add above*********/
class Solution {
public:
string decodeString(string s) {
string ans = "";
Stack* st=new Stack();
for (unsigned i = 0; i < s.length(); i++) {
if (s[i] != ']')st->push(s[i]);
else {
string ss = "", num = "";
while (st->top() != '[') {
ss += st->top();
st->pop();
}
st->pop();
/*Delete '[' character*/
reverse(ss.begin(), ss.end());
while (!st->empty() && st->top() <= '9'&&st->top() >= '0') {
num += st->top();
st->pop();
}
unsigned times = 0, index = 1;
for (unsigned i = 0; i < num.length(); i++, index =index* 10) {
times += index * (num[i]-'0');
}
string sss ="";
for (unsigned i = 0; i < times; i++) {
sss += ss;
}
for (unsigned i = 0; i < sss.length(); i++) {
st->push(sss[i]);
}
}
}
/******change below********/
for (char it : st->ll) {
ans += it;
}
/******change above********/
delete st;
return ans;
}
};

[Leetcode]394.字符串解码的更多相关文章

  1. LeetCode 394. 字符串解码(Decode String) 44

    394. 字符串解码 394. Decode String 题目描述 给定一个经过编码的字符串,返回它解码后的字符串. 编码规则为: k[encoded_string],表示其中方括号内部的 enco ...

  2. Java实现 LeetCode 394 字符串解码

    394. 字符串解码 给定一个经过编码的字符串,返回它解码后的字符串. 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次.注意 k ...

  3. [LeetCode]394. 字符串解码(栈)

    题目 给定一个经过编码的字符串,返回它解码后的字符串. 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次.注意 k 保证为正整数. ...

  4. Leetcode 394.字符串编码

    字符串编码 给定一个经过编码的字符串,返回它解码后的字符串. 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次.注意 k 保证为正 ...

  5. [LeetCode] 394. Decode String 解码字符串

    Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...

  6. [LeetCode] Decode String 解码字符串

    Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...

  7. 字符串解码DecodeString

    字符串解码 原创博客,转载请注明出处!eg:ss=2[abc]3[cd]ef   return:abcabccdcdcdefss=3[a2[c]]2[a]    return:accaccaccaas ...

  8. [PHP]对Json字符串解码返回NULL的一般解决方案

    ---------------------------------------------------------------------------------------------------- ...

  9. Leetcode中字符串总结

    本文是个人对LeetCode中字符串类型题目的总结,纯属个人感悟,若有不妥的地方,欢迎指出. 一.有关数字 1.数转换 题Interger to roman和Roman to integer这两题是罗 ...

随机推荐

  1. “AS3.0高级动画编程”学习:第三章等角投影(上)

    什么是等角投影(isometric)? 原作者:菩提树下的杨过出处:http://yjmyzz.cnblogs.com 刚接触这个概念时,我也很茫然,百度+google了N天后,找到了一些文章: [转 ...

  2. as3中的embed

    actionscript3允许把外部swf直接用Embed标记嵌入到主类中(当然用UrlLoader动态加载也行) 原 作者:菩提树下的杨过出处:http://yjmyzz.cnblogs.com 关 ...

  3. python--第九天总结

    python 多进程和多线程 多线程可以共享全局变量,多进程不能.多线程中,所有子线程的进程号相同:多进程中,不同的子进程进程号不同. [多进程] Python在2.6引入了多进程的机制,并提供了丰富 ...

  4. JDK、JRE、JVM的区别

    JDK: JDK(Java Development Kit)顾名思义它是给开发者提供的开发工具箱,是给程序开发者用的.它除了包括完整的JRE(Java Runtime Environment),Jav ...

  5. linux之重定向命令

    1.shell重定向概念:shell重定向包含输出重定向和输入重定向 何为输入输出方向?何为标准输入输出方向? 标准输入方向:从键盘读取用户输入的数据,然后再把数据拿到程序(C语言程序.Shell 脚 ...

  6. 英雄联盟lol登录错误:登录服务器未响应、您可能遇到了一个网络问题、请检查您的网络。

    第一方法cmd 用管理员命令打开,输入  netsh winsock reset.重启 第二种方法  win+r 输入 regedit  在 HKEY_CURRENT_USER\Software\Mi ...

  7. bootstrap 辅助工具

    模板  https://startbootstrap.com/ 可视化bootstrap在线编辑器 https://www.layoutit.com/

  8. vue-computed计算属性

    计算属性:用来封装你想对一个属性进行的操作 computed VS mothod实现的效果和定义一个methods中的function相同,但是他们的区别在于:methods的function当触发重 ...

  9. Java内存泄露监控工具:JVM监控工具介绍

    本文将对JVM监控工具jstack, jconsole, jinfo, jmap, jdb, jstat进行详细的介绍,具体内容请看下文 Sun JDK监控和故障处理工具 名称 主要作用 jps JV ...

  10. Linux学习小记(1)

    学习Linux,进行阶段性总结,权当笔记方便日后翻阅和查看. 在此特别推荐peida的博客,他的有关Linux的理解个人感觉深入浅出,很适合入门的小白来理解和学习. 说一说针对IP的修改,ifconf ...