LeetCode 「中等」394.字符串解码

sankigan2025-3-14算法LeetCode

字符串解码open in new window

题目描述

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

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

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

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

示例

输入:s = "3[a]2[bc]"
输出:"aaabcbc"

输入:s = "3[a2[c]]"
输出:"accaccacc"

输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"

输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"

解答

正则表达式

Code
/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function(s) {
  while (s.includes('[')) {
    s = s.replace(/(\d+)\[(\w+)\]/g, (match, p1, p2) => {
      return p2.repeat(+p1);
    });
  }
  return s;
};

思路

  1. 使用栈来处理嵌套结构
  • 遍历字符串时,遇到数字和字母时直接处理
  • 遇到 [ 时,将当前的数字和字符串压入栈中
  • 遇到 ] 时,从栈中弹出最近的数字和字符串,并将当前字符串重复指定次数,然后拼接到之前的字符串上
  1. 遍历字符串
  • 使用一个变量 currentNum 来记录当前的数字
  • 使用一个变量 currentStr 来记录当前的字符串片段
  • 遍历输入字符串的每个字符:
    • 如果是数字,更新 currentNum
    • 如果是字母,直接添加到 currentStr
    • 如果是 [,将 currentNumcurrentStr 压入栈中,然后重置它们
    • 如果是 ],从栈中弹出最近的数字和字符串,将 currentStr 重复指定次数,然后拼接到弹出的字符串上
  1. 返回最终结果
  • 遍历结束后,currentStr 就是解码后的字符串
Code
/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function(s) {
  const stack = []; // 用于存储数字和字符串
  let currentNum = 0; // 当前数字
  let currentStr = ''; // 当前字符串片段

  for (let i = 0; i < s.length; ++i) {
    const char = s[i];

    if (/\d/.test(char)) {
      // 如果是数字,更新 currentNum
      currentNum = currentNum * 10 + char * 1;
    } else if (/[a-zA-Z]/.test(char)) {
      // 如果是字母,更新 currentStr
      currentStr += char;
    } else if (char === '[') {
      // 如果是 [,将 currentNum 和 currentStr 压入栈中
      stack.push([currentNum, currentStr]);
      currentNum = 0; // 重置 currentNum
      currentStr = ''; // 重置 currentStr
    } else if (char === ']') {
      // 如果是 ],从栈中弹出最近的数字和字符串
      const [num, prevStr] = stack.pop();
      // 将 currentStr 重复 num 次,并拼接到 prevStr 上
      currentStr = prevStr + currentStr.repeat(num);
    }
  }

  return currentStr;
};
更新于 2025/3/14 20:33:32