题目描述
给定一个以字符串表示的任意嵌套的三元表达式,计算表达式的值。你可以假定给定的表达式始终都是有效的并且只包含数字 0-9
, ?
, :
, T
和 F
(T
和 F
分别表示真和假)。
注意:
- 给定的字符串长度 ≤ 10000。
- 所包含的数字都只有一位数。
- 条件表达式从右至左结合(和大多数程序设计语言类似)。
- 条件是
T
和F
其一,即条件永远不会是数字。 - 表达式的结果是数字
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)