分治法_medium_439_三元表达式解析器

文章目录

题目描述

给定一个以字符串表示的任意嵌套的三元表达式,计算表达式的值。你可以假定给定的表达式始终都是有效的并且只包含数字 0-9, ?, :, TF (TF 分别表示真和假)。

注意:

  1. 给定的字符串长度 ≤ 10000。
  2. 所包含的数字都只有一位数。
  3. 条件表达式从右至左结合(和大多数程序设计语言类似)。
  4. 条件是 TF其一,即条件永远不会是数字。
  5. 表达式的结果是数字 0-9, T 或者 F

示例 1:

输入: “T?2:3”
输出: “2”
解释: 如果条件为真,结果为 2;否则,结果为 3。

示例 2:

输入: “F?1:T?4:5”
输出: “4”
解释: 条件表达式自右向左结合。使用括号的话,相当于:
“(F ? 1 : (T ? 4 : 5))” “(F ? 1 : (T ? 4 : 5))”
-> “(F ? 1 : 4)” 或者 -> “(T ? 4 : 5)”
-> “4” -> “4”

示例 3:

输入: “T?T?F:5:3”
输出: “F”
解释: 条件表达式自右向左结合。使用括号的话,相当于:
“(T ? (T ? F : 5) : 3)” “(T ? (T ? F : 5) : 3)”
-> “(T ? F : 3)” 或者 -> “(T ? F : 5)”
-> “F” -> “F”

思路

咋一看到这道题目,感觉可以用 栈 解决(后续添加代码),但由于条件表达式T ? a : b存在嵌套关系,一种更简单的方法是 分治

  • 对于 T ? T ? T ? ... a : b : c,其中?: 的对应关系是 第1?号 对应 第i: 号。其中i 计算方式为 该冒号前面的 问号 数量 和 冒号数量(包括该冒号)相等。
  • 例如 T ? T ? a : b : c ,第一个冒号 和 第二个冒号对应,(第2个冒号【含该冒号】前面有2个冒号和两个问号)
  • 据此 定义一个切分函数 split_method(ex) ,该函数返回第一个问号和对应冒号的下标
  • 然后根据条件,分治解决,即递归的判断 冒号两端的内容
  • 递归边界为 有效内容长度为1,因为题目说了:表达式的结果是数字 0-9, T 或者 F

完整代码如下:

class Solution:
    def parseTernary(self, expression: str) -> str:
        def split_method(expression):  # 按冒号切分
            cnt_question, cnt_point = 0, 0  # 分别统计问好 和 冒号的数量
            first_index, last_index = -1, -1
            for i, one in enumerate(expression):
                if one == "?":
                    cnt_question += 1
                    if first_index < 0:
                        first_index = i
                elif one == ":":
                    cnt_point += 1
                    if cnt_point == cnt_question:
                        last_index = i 
                        break
            return expression[first_index+1:last_index], expression[last_index+1:]
        
        def dfs(expression):
            a, b = split_method(expression)
            if expression[0] != "F" and expression[0] != "0":
                return a if len(a) == 1 else dfs(a)
            else:
                return b if len(b) == 1 else dfs(b)
        
        return dfs(expression)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值