老卫带你学---leetcode刷题(1096. 花括号展开 II)

1096. 花括号展开 II

问题:

如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串。

花括号展开的表达式可以看作一个由 花括号、逗号 和 小写英文字母 组成的字符串,定义下面几条语法规则:

如果只给出单一的元素 x,那么表达式表示的字符串就只有 “x”。R(x) = {x}
例如,表达式 {“a”} 表示字符串 “a”。
而表达式 {“w”} 就表示字符串 “w”。
当两个或多个表达式并列,以逗号分隔时,我们取这些表达式中元素的并集。R({e_1,e_2,…}) = R(e_1) ∪ R(e_2) ∪ …
例如,表达式 “{a,b,c}” 表示字符串 “a”,“b”,“c”。
而表达式 “{{a,b},{b,c}}” 也可以表示字符串 “a”,“b”,“c”。
要是两个或多个表达式相接,中间没有隔开时,我们从这些表达式中各取一个元素依次连接形成字符串。R(e_1 + e_2) = {a + b for (a, b) in R(e_1) × R(e_2)}
例如,表达式 “{a,b}{c,d}” 表示字符串 “ac”,“ad”,“bc”,“bd”。
表达式之间允许嵌套,单一元素与表达式的连接也是允许的。
例如,表达式 “a{b,c,d}” 表示字符串 “ab”,“ac”,"ad"​​​​​​。
例如,表达式 “a{b,c}}{{d,e}f{g,h}” 可以表示字符串 “abdfg”, “abdfh”, “abefg”, “abefh”, “acdfg”, “acdfh”, “acefg”, “acefh”。
给出表示基于给定语法规则的表达式 expression,返回它所表示的所有字符串组成的有序列表。

假如你希望以「集合」的概念了解此题,也可以通过点击 “显示英文描述” 获取详情。

示例 1:

输入:"{a,b}{c,{d,e}}"
输出:["ac","ad","ae","bc","bd","be"]

示例 2:

输入:"{{a,z},a{b,c},{ab,z}}"
输出:["a","ab","ac","z"]

解释:输出中 不应 出现重复的组合结果。

提示:

1 <= expression.length <= 50
expression[i] 由 ‘{’,’}’,’,’ 或小写英文字母组成
给出的表达式 expression 用以表示一组基于题目描述中语法构造的字符串

解决:

思想:

使用压栈来存储当前括号的状态,如果遇到新的左括号,将当前确定和未确定的元素集合保存起来。
当遇到右括号,将当前所有未确定加入确定中,并出栈,将确定加入到上一层的未确定中(相乘)。
具体代码与详细注释如下。

python代码:

class Solution:
    def braceExpansionII(self, expression: str) -> List[str]:
        stack = [set(), {''}]
        for c in expression:
            if c == '{':
                stack.append(set()) # 压入 当前层已经确定元素集合
                stack.append({''}) # 压入 当前层未确定元素集合
            elif c == '}':
                unknow = stack.pop() # 出栈
                know = stack.pop() | unknow # 合并两个集合,由于遇见},未确定的集合可以并入到已确定集合中
                stack[-1] = {i+j for i in stack[-1] for j in know} # 将当前层与上一层未确定元素相×,完成出栈
            elif c == ',':
                # 未确定元素可以确定结束
                stack[-2] = stack[-1] | stack[-2] # 将未确定元素加入确定元素集合中
                stack[-1] = {''} # 未确定元素清0
            else:
                # 输入的为字母,直接与未确定元素集合×上当前字母
                stack[-1] = {i+c for i in stack[-1]}
        return sorted(list(stack[-1]|stack[-2]))


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值