题目:

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

Given an encoded string, return its decoded string.

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

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.

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

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].

示例:

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

解题思路:

​ 这道题类似我们之前做过的一道题:有效的括号: https://mp.weixin.qq.com/s/Sm1S26EgR-dC75hrhVnZGQ

只不过''有效的括号'' [] 内多了一些字符串需要操作。我们同样可以用数据结构栈来解题,,能用栈解决的题目大部分都可以用递归解决,两者逻辑基本相同:

输入:'3[a2[c]]'
初始化栈: 栈nums 存要重复的次数k,栈str 存字符串 遍历字符串:
指针指向字符'3',为数字
num暂存数字3 继续遍历,遇到字符'['
循环次数num入栈nums,空字符串res入栈str
nums: 3 res: ''
num置为0,str置空 继续遍历,遇到字符'a',为字母
空字符串res拼接字母'a',res='a' 继续遍历,遇到字符'2',为数字
num暂存数字2 继续遍历遇到字符'['
num入栈nums,res入栈str
nums: 3 -> 2 str: '' -> 'a'
num置为0,str置空 继续遍历,遇到字符'c',为字母
空字符串res拼接字母'c',res='c' 继续遍历遇到字符']'
nums弹出栈顶元素:当前字符串重复次数2
res = res*2 = 'cc'
str弹出栈顶元素'a'与res拼接并入栈:
res = 'a'+'cc'='acc'
str: '' -> 'acc' 继续遍历遇到字符']'
nums弹出栈顶元素:当前字符串重复次数3
res = res*3 = 'accaccacc'
str弹出栈顶元素空字符串''与res拼接并入栈:
res=''+'accaccacc'='accaccacc'
str: 'accaccacc' 结束返回res

注意:

  • 由于重复次数可能大于10,所以暂存数字时要适当处理,如 num*10+当前数字
  • 在c++里可以直接修改拼接字符,但Java不支持运算符重载,可以借助 StringBuilder 或 StringBuffer 类。
  • 用栈暂存的逻辑与递归基本一致,可以理解为用递归实现栈。
  • python没有栈这种数据结构,可以用 list() 数组或双端队列 deque()
  • python可以只用一个栈以元组的形式重复次数和字符串,如(num,res)

利用栈:

Java:

class Solution {
public String decodeString(String s) {
//初始化数据结构
Stack<StringBuilder> str = new Stack<>();
Stack<Integer> nums = new Stack<>();
StringBuilder res = new StringBuilder();
int num = 0;
for (char c : s.toCharArray()) {//递归字符串
if (c == '[') {
str.push(res);//入栈
nums.push(num);
num = 0;//刷新num、res
res = new StringBuilder();
} else if (c == ']') {
StringBuilder tmp = new StringBuilder();
for (int i = nums.pop(); i > 0; i--) tmp.append(res);//res*3
res = str.pop().append(tmp);
} else if (c >= '0' && c <= '9') num = num * 10 + (c - '0');//计算重复次数
else res.append(c);
}
return res.toString();
}
}

Python:

可直接操作字符串真的很方便。py里有现成的判断字符串的方法:

  • isdigit() 是否为只包含数字的字符串
  • isalpha() 是否为只包含字母的字符串
class Solution:
def decodeString(self, s: str) -> str:
#初始化数据结构
stack, res, num = [], '', 0
for c in s:
if c.isdigit():
num = num * 10 + int(c)
elif c.isalpha():
res += c
elif c == '[':
#元组形式入栈
stack.append((res, num))
#刷新字符串和重复次数
res, num = '', 0
else:
#如果c==']',弹出字符串和重复次数
last_str, this_num = stack.pop()
res = last_str + this_num * res
return res

利用递归:

Java:

将 s.length() 的值以参数传递,减少重复调用 length() 造成的时间损耗

class Solution {
private int i = -1;//全局变量i,记录字符数组指针位置 public String decodeString(String s) {
return dfs(s.toCharArray(), s.length()).toString();
}
//递归函数
private StringBuilder dfs(char[] chars, int len) {
int num = 0;
StringBuilder str = new StringBuilder();
while (++i < len) {
if (chars[i] >= '0' && chars[i] <= '9')
num = num * 10 + (chars[i] - '0');
else if (chars[i] == '[') {
StringBuilder tmp = dfs(chars, len);//递归调用
while (--num >= 0) str.append(tmp);//重复字符串res=res*num
num = 0;
} else if (chars[i] == ']') return str;
else str.append(chars[i]);
}
return str;
}
}

Python:

class Solution:
i = -1
#递归函数,可以直接操作字符串就无需再建一个dfs辅助函数
def decodeString(self, s: str) -> str:
res, num = '', 0
while self.i < len(s) - 1:
self.i += 1
if s[self.i].isdigit():
num = num * 10 + int(s[self.i])
elif s[self.i].isalpha():
res += s[self.i]
elif s[self.i] == '[':
#递归调用
res += self.decodeString(s) * num
num = 0
elif s[self.i] == ']':
return res
return res

欢迎关注微.信公.众号:爱写Bug

LeetCode 394:字符串解码 Decode String的更多相关文章

  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. [Swift]LeetCode394. 字符串解码 | Decode String

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

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

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

  5. [Leetcode]394.字符串解码

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

  6. Leetcode 394.字符串编码

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

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

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

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

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

  9. [LeetCode] 271. Encode and Decode Strings 加码解码字符串

    Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...

随机推荐

  1. LeetCode 217:存在重复元素 Contains Duplicate

    题目: 给定一个整数数组,判断是否存在重复元素. Given an array of integers, find if the array contains any duplicates. 如果任何 ...

  2. Unity Package包内插件解锁

    起因: 新版的Unity将模块工具与游戏中的资源文件分开放置,但有一个问题,里边的插件都是只读的,无法添加内容,连创建都是灰色的orz: 要想给这些插件添加一些别的自定义功能,那基本等于做梦,而且插件 ...

  3. Jenkins操作学习 --初始化安装

    前言 说到持续集成,可以说是当下比较热门的话题了,也是很多公司和It从业者推崇的热门技术,但在项目中真正实际应用起来的并不太多,但通过持续集成带来的好处还是值得学习和推广的. 1.什么是jenkins ...

  4. linq根据两个时间求出天数

    对于在Linq To Entity里使用日期函数需要DbFunctions里的扩展方法,而不能使用.net里的日期函数,因为linq的代码会被翻译成SQL发到数据库端,如你的.net方法对于数据库是不 ...

  5. C# - VS2019通过重写pictureBox实现简单的桌面截图功能

    前言 通过创建客制化组件(继承pictureBox),新增属性和构造方法,实现屏幕截图时需要用到的功能点.再通过监控鼠标按下.移动和释放,来获取起始点区域.最后通过操作BMP图像,实现截图的新增.修改 ...

  6. Z从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之九 || 依赖注入IoC学习 + AOP界面编程初探

    本文梯子 本文3.0版本文章 更新 代码已上传Github+Gitee,文末有地址 零.今天完成的绿色部分 一.依赖注入的理解和思考 二.常见的IoC框架有哪些 1.Autofac+原生 2.三种注入 ...

  7. MySQL基础(MySQL5.7安装、配置)

      写在前面: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQ ...

  8. Threads(异步和多线程)

    Task是.NET Framework4.5出现的,线程是基于线程池的,然后提供丰富的api,Thread方法很多很强大,但是太过强大,没有限制. DoSomethingLong方法如下: /// & ...

  9. LayoutSubviews的调用

    1.当view被添加到另一个view上时调用 2.布局子控件时调用 3.屏幕旋转的时候调用 4.当view的尺寸大小改变的时候调用

  10. mssql的text字段中文乱码

    问题: 1.在页面存入中文后乱码,从前端从后台发现数据未发生异常,发现是存入数据库后乱码: 经查询该字段为text字段,存入中文会乱码 如图 解决办法: 1.将text转为varchar或nvarch ...