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)
        }
    }
    
  • 相关阅读:
    浅谈软件开发项目的质量控制
    分布式系统稳定性模式
    正确使用 Volatile 变量
    我和 OI 的一些故事
    NOIP2020 退役记
    博弈论基础入门
    [HAOI2008]硬币购物(容斥/背包DP)
    [CF] 1307F Cow and Vacation(思维/贪心)
    [noi.ac 模拟赛8] c(容斥/DP)
    [noi.ac 模拟赛9] A.出征准备(同余最短路)
  • 原文地址:https://www.cnblogs.com/zhongju/p/13957156.html
Copyright © 2011-2022 走看看