亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

LeetCode 394:字符串解碼 Decode String

標簽:
Java Python 算法

题目:

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

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
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.

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.

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

示例:

s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".

解题思路:

​ 这道题类似我们之前做过的一道题:有效的括号: https://mp.weixin.qq.com/s/Sm1S26EgR-dC75hrhVnZGQ

只不过’‘有效的括号’’ [] 内多了一些字符串需要操作。我们同样可以用数据结构栈来解题,,能用栈解决的题目大部分都可以用递归解决,两者逻辑基本相同:

输入:'3[a2[c]]'
初始化栈: 栈nums 存要重复的次数k,栈str 存字符串

遍历字符串:
指针指向字符'3',为数字
num暂存数字3

继续遍历,遇到字符'['
循环次数num入栈nums,空字符串res入栈str
nums: 3		res: ''
num置为0,str置空

继续遍历,遇到字符'a',为字母
空字符串res拼接字母'a',res='a'

继续遍历,遇到字符'2',为数字
num暂存数字2

继续遍历遇到字符'['
num入栈nums,res入栈str
nums: 3 -> 2	str: '' -> 'a'
num置为0,str置空

继续遍历,遇到字符'c',为字母
空字符串res拼接字母'c',res='c'

继续遍历遇到字符']'
nums弹出栈顶元素:当前字符串重复次数2
res = res*2 = 'cc'
str弹出栈顶元素'a'与res拼接并入栈:
res = 'a'+'cc'='acc'
str: '' -> 'acc'

继续遍历遇到字符']'
nums弹出栈顶元素:当前字符串重复次数3
res = res*3 = 'accaccacc'
str弹出栈顶元素空字符串''与res拼接并入栈:
res=''+'accaccacc'='accaccacc'
str: 'accaccacc'

结束返回res

注意:

  • 由于重复次数可能大于10,所以暂存数字时要适当处理,如 num*10+当前数字
  • 在c++里可以直接修改拼接字符,但Java不支持运算符重载,可以借助 StringBuilder 或 StringBuffer 类。
  • 用栈暂存的逻辑与递归基本一致,可以理解为用递归实现栈。
  • python没有栈这种数据结构,可以用 list() 数组或双端队列 deque()
  • python可以只用一个栈以元组的形式重复次数和字符串,如(num,res)

利用栈:

Java:

class Solution {
    public String decodeString(String s) {
        //初始化数据结构
        Stack<StringBuilder> str = new Stack<>();
        Stack<Integer> nums = new Stack<>();
        StringBuilder res = new StringBuilder();
        int num = 0;
        for (char c : s.toCharArray()) {//递归字符串
            if (c == '[') {
                str.push(res);//入栈
                nums.push(num);
                num = 0;//刷新num、res
                res = new StringBuilder();
            } else if (c == ']') {
                StringBuilder tmp = new StringBuilder();
                for (int i = nums.pop(); i > 0; i--) tmp.append(res);//res*3
                res = str.pop().append(tmp);
            } else if (c >= '0' && c <= '9') num = num * 10 + (c - '0');//计算重复次数
            else res.append(c);
        }
        return res.toString();
    }
}

Python:

可直接操作字符串真的很方便。py里有现成的判断字符串的方法:

  • isdigit() 是否为只包含数字的字符串
  • isalpha() 是否为只包含字母的字符串
class Solution:
    def decodeString(self, s: str) -> str:
        #初始化数据结构
        stack, res, num = [], '', 0
        for c in s:
            if c.isdigit():
                num = num * 10 + int(c)
            elif c.isalpha():
                res += c
            elif c == '[':
                #元组形式入栈
                stack.append((res, num))
                #刷新字符串和重复次数
                res, num = '', 0
            else:
                #如果c==']',弹出字符串和重复次数
                last_str, this_num = stack.pop()
                res = last_str + this_num * res
        return res

利用递归:

Java:

将 s.length() 的值以参数传递,减少重复调用 length() 造成的时间损耗

class Solution {
    private int i = -1;//全局变量i,记录字符数组指针位置
    
    public String decodeString(String s) {
        return dfs(s.toCharArray(), s.length()).toString();
    }
	//递归函数
    private StringBuilder dfs(char[] chars, int len) {
        int num = 0;
        StringBuilder str = new StringBuilder();
        while (++i < len) {
            if (chars[i] >= '0' && chars[i] <= '9')
                num = num * 10 + (chars[i] - '0');
            else if (chars[i] == '[') {
                StringBuilder tmp = dfs(chars, len);//递归调用
                while (--num >= 0) str.append(tmp);//重复字符串res=res*num
                num = 0;
            } else if (chars[i] == ']') return str;
            else str.append(chars[i]);
        }
        return str;
    }
}

Python:

class Solution:
    i = -1
	#递归函数,可以直接操作字符串就无需再建一个dfs辅助函数
    def decodeString(self, s: str) -> str:
        res, num = '', 0
        while self.i < len(s) - 1:
            self.i += 1
            if s[self.i].isdigit():
                num = num * 10 + int(s[self.i])
            elif s[self.i].isalpha():
                res += s[self.i]
            elif s[self.i] == '[':
                #递归调用
                res += self.decodeString(s) * num
                num = 0
            elif s[self.i] == ']':
                return res
        return res
點擊查看更多內容
1人點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
算法工程師
手記
粉絲
17
獲贊與收藏
44

關注作者,訂閱最新文章

閱讀免費教程

感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消