zoukankan      html  css  js  c++  java
  • [LeetCode] 394. Decode String(解码字符串)

    Description

    Given an encoded string, return its decoded string.
    给一个编码过的字符串,返回解码后的字符串。

    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.
    编码规则是 k[encoded_string],其中方括号内部的 encoded_string 需要重复正好 k 次。输入保证 k 是一个正数。

    You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.
    你可以假定输入总是合法的;没有多余的空格,方括号总是合法的等。

    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].
    并且,你可以假定解码后的字符串不含任何数字,换句话说,编码字符串里的数字永远只表示重复的次数。例如,没有像 3a2[4] 这样的输入。

    Examples

    Example 1

    Input: s = "3[a]2[bc]"
    Output: "aaabcbc"
    

    Example 2

    Input: s = "3[a2[c]]"
    Output: "accaccacc"
    

    Example 3

    Input: s = "2[abc]3[cd]ef"
    Output: "abcabccdcdcdef"
    

    Example 4

    Input: s = "abc3[cd]xyz"
    Output: "abccdcdcdxyz"
    

    Solution

    一道手写解析器的题目,耐着性子按规则来就问题不大:

    • 遇到数字:开始记录重复次数;

    • 遇到左方括号 [:进入递归处理,处理过程中消耗对应的右方括号 ]

    • 遇到其它情况:直接加入结果集。‘

    我自己的代码如下(这个代码自认写得有点难看):

    class Solution {
        fun decodeString(s: String): String {
            val result = StringBuilder()
            var i = 0
            var repeatedTime = 0
            while (i < s.length) {
                val ch = s[i]
                when {
                    ch.isDigit() -> {
                        repeatedTime = 10 * repeatedTime + ch.numericValue()
                        i++
                    }
                    ch == '[' -> {
                        i = doRepeat(s, i + 1, repeatedTime, result)
                        repeatedTime = 0
                    }
                    else -> {
                        result.append(ch)
                        i++
                    }
                }
            }
            return result.toString()
        }
    
        private fun doRepeat(s: String, startIndex: Int, repeatTime: Int, result: Appendable): Int {
            var i = startIndex
            val sb = StringBuilder()
            var innerRepeatTime = 0
            while (i < s.length && s[i] != ']') {
                val ch = s[i]
                when {
                    ch.isDigit() -> {
                        innerRepeatTime = 10 * innerRepeatTime + ch.numericValue()
                        i++
                    }
                    ch == '[' -> {
                        i = doRepeat(s, i + 1, innerRepeatTime, sb)
                        innerRepeatTime = 0
                    }
                    else -> {
                        sb.append(ch)
                        i++
                    }
                }
            }
            result.append(sb.repeat(repeatTime))
            return i + 1
        }
    
        private fun Char.numericValue(): Int {
            return Character.getNumericValue(this)
        }
    }
    

    我这个解法虽然能解题,但总感觉写得不够优雅,翻阅 discussion,找到了个和我类似的解法,但这个递归比我的优雅多了:

    import java.util.*
    
    class Solution {
        fun decodeString(s: String): String {
            val queue: Queue<Char> = ArrayDeque()
            s.forEach { queue.offer(it) }
            return helper(queue)
        }
    
        private fun helper(queue: Queue<Char>): String {
            val result = StringBuilder()
            var repeatTime = 0
            loop@ while (queue.isNotEmpty()) {
                val c = queue.poll()
                when {
                    c.isDigit() -> repeatTime = 10 * repeatTime + c.numericValue()
                    c == '[' -> {
                        val repeatStr = helper(queue)
                        result.append(repeatStr.repeat(repeatTime))
                        repeatTime = 0
                    }
                    c == ']' -> {
                        break@loop
                    }
                    else -> {
                        result.append(c)
                    }
                }
            }
            return result.toString()
        }
    
        private fun Char.numericValue(): Int {
            return Character.getNumericValue(this)
        }
    }
    
  • 相关阅读:
    [THUWC2017]在美妙的数学王国中畅游 LCT+泰勒展开+求导
    luoguP4238 【模板】多项式求逆
    Bzoj 2502: 清理雪道 有上下界网络流_最小流
    [十二省联考2019]字符串问题 后缀自动机 + 拓扑排序 + 最长路 + 倍增
    luogu P5290 [十二省联考2019]春节十二响 优先队列 + 启发式合并
    bzoj 2648: SJY摆棋子 KDtree + 替罪羊式重构
    os模块,sys模块
    datetime模块,random模块
    终端打印覆盖打印,让加载界面更加好看
    time模块
  • 原文地址:https://www.cnblogs.com/zhongju/p/13957156.html
Copyright © 2011-2022 走看看