leetcode hot100之字符串解码(394)解析

202 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情


前言

  • leetcode hot100,是大厂面试高频题,也是必刷算法题。精选了100道LeetCode上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,按照官方说的,熟练掌握这 100 道题,就具备了代码世界通行的基本能力。

leetcode394题(字符串解码)

本文来讲hot100第394题( 字符串解码),此题细节点比较多,直接看例子很容易懂,也是练习双栈解法的一个题目。

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

编码规则为: 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"
输入: s = "abc3[cd]xyz"
输出: "abccdcdcdxyz"

提示:

  • 1 <= s.length <= 30
  • s 由小写英文字母、数字和方括号 '[]' 组成
  • s 保证是一个 有效 的输入。
  • s 中所有整数的取值范围为 [1, 300]

分析

  • k为次数,[encoded_string]被为重复的字符串
  • 可能出现嵌套的情况
  • []前没数字表示1

思路

  • 用两个栈来存储数据,一个代表次数,一个代表内容
  • 例子一:
    1. 3 - a
    2. 2 - bc
    3. 3 * a + 2 * bc
  • 例子二:
    1. 3 - [a2[c]] // 注意 这里的值又是一个栈
    2. 3的子栈 a2[c]开始执行:
    3. a前面没有数字就是1
    4. 3 --- > 1 - a
    5. 3 --- > 2 - c
    6. 3 * ( 1 * a + 2 * c )

代码

const countStack = [],
innerStack = [];
// 一个记录次数,一个记录内容
let countNum = "",
innerStr = "";
for (let i = 0; i < s.length; i++) {
    let curr = s.charAt(i);
    // 如果是数字
    if (!isNaN(curr)) {
      countNum += curr;
    } else if (curr === "[") {
      // 双双压入栈中,保存当前状态
      countStack.push(countNum);
      innerStack.push(innerStr);
      // 清空记录的内容
      countNum = "";
      innerStr = "";
    } else if (curr === "]") {
      // 取出当前重复次数栈中的值,也就是当前字符串的重复次数
      const count = countStack.pop();
      // 根据重复次数生成重复字符串,赋值给temp,和innerStr拼接
      let temp = "";
      for (let i = 0; i < count; i++) {
        temp += innerStr;
      }
      // 和前面已经求得的字符串进行拼接
      innerStr = innerStack.pop() + temp;
    } else {
      innerStr += curr;
    }
}
return innerStr;

结语

  • 本题相对来说难度不大,直接看例子很容易理解题目意思,能想到用两个stack去分别存储字符串与出现的次数就完成了一半,做出本题关键在于能想到[是压栈,]是出栈。