🚩传送门:力扣题目

题目

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

编码规则为: [LC]394. 字符串解码 - 图1,表示其中方括号内部的 [LC]394. 字符串解码 - 图2 正好重复 [LC]394. 字符串解码 - 图3 次。注意 [LC]394. 字符串解码 - 图4 保证为正整数。

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

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 [LC]394. 字符串解码 - 图5 ,例如不会出现像 [LC]394. 字符串解码 - 图6[LC]394. 字符串解码 - 图7 的输入。

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

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

解题思路:栈

本题中可能出现括号嵌套的情况,比如 [LC]394. 字符串解码 - 图8,这种情况下我们可以先转化成 [LC]394. 字符串解码 - 图9,在转化成 [LC]394. 字符串解码 - 图10

  • 如果 栈空,当前字符为字母,直接入结果集 [LC]394. 字符串解码 - 图11
  • 如果 栈非空,除了[LC]394. 字符串解码 - 图12,数字字母等一律入栈
  1. 当遇到[LC]394. 字符串解码 - 图13右括号时,将栈中字符出栈,直至[LC]394. 字符串解码 - 图14左括号,得到 字母集[LC]394. 字符串解码 - 图15注意顺序问题

    ab 入栈,出栈后会变成 ba,因此在 StringBuilder 中使用 nonamefrom.insert(0, stack.pop());

  2. 再遍历[LC]394. 字符串解码 - 图16左括号栈中的数字

  3. 得到 数字×字母集 [LC]394. 字符串解码 - 图17,如果 栈空 直接入结果集 [LC]394. 字符串解码 - 图18,如果 栈非空,将[LC]394. 字符串解码 - 图19入栈
  4. 直至遍历结束栈空

官方代码

  1. import java.util.LinkedList;
  2. class Solution {
  3. public static String decodeString(String s) {
  4. char[] str = s.toCharArray();
  5. LinkedList<String> stack = new LinkedList<>();
  6. StringBuilder sb = new StringBuilder();
  7. for (int i = 0; i < str.length; i++) {
  8. // 栈空,字符入结果集
  9. if (stack.isEmpty() && 'a' <= str[i] && str[i] <= 'z') {
  10. sb.append(str[i]);
  11. continue;
  12. }
  13. // 栈非空时, 除非是 ] ,否则全入栈
  14. if (!stack.isEmpty() && str[i] == ']') {
  15. StringBuilder nonamefrom = new StringBuilder();
  16. // 将[ 括号前的字符全部取出
  17. while (!stack.isEmpty() && !stack.peek().equals("[")) {
  18. nonamefrom.insert(0, stack.pop());
  19. }
  20. // 吐出 [
  21. if (!stack.isEmpty()) stack.pop();
  22. StringBuilder num = new StringBuilder();
  23. // 查看 [ 前面是否有数字
  24. while (!stack.isEmpty() && stack.peek().length() == 1
  25. && '0' <= stack.peek().charAt(0) && stack.peek().charAt(0) <= '9') {
  26. num.append(stack.pop());
  27. }
  28. int intnum = 0;
  29. if (num.length() != 0)
  30. intnum = Integer.valueOf(num.reverse().toString());
  31. // 获取 数字×[字符]
  32. StringBuilder nonameTo = new StringBuilder();
  33. for (int j = 0; j < intnum; j++) {
  34. nonameTo.append(nonamefrom.toString());
  35. }
  36. // 保存进结果集或者入栈
  37. if (stack.isEmpty()) {
  38. sb.append(nonameTo.toString());
  39. } else {
  40. stack.push(nonameTo.toString());
  41. }
  42. } else {
  43. stack.push(str[i] + "");
  44. }
  45. }
  46. return sb.toString();
  47. }
  48. }