版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/84638112
给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +
, -
以及 *
。
示例 1:
输入: "2-1-1"
输出: [0, 2]
解释:
((2-1)-1) = 0
(2-(1-1)) = 2
示例 2:
输入: "2*3-4*5"
输出: [-34, -14, -10, -10, 10]
解释:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
解题思路
这个问题非常简单,和之前问题Leetcode 96:不同的二叉搜索树(超详细的解法!!!)、Leetcode 95:不同的二叉搜索树 II(超详细的解法!!!)类似。我们首先想到的解法是通过递归,我们可以这样思考。我们考虑操作符的位置
,我们定义
返回输入为input
的所有结果,那么
左边的结果就是
,
右边的结果就是
,此时我们以
为考虑对象时的所有结果就是
left = self._diffWaysToCompute(input[0:i])
right = self._diffWaysToCompute(input[i+1:])
for l in left:
for r in right:
res.append(self._calc(l, input[i], r))
我们的
的范围就是[1,len(input))
,每次步长为2
。如果你对这个过程有困惑的话,一定要阅读我说的那两篇文章。
我们就非常容易的得到下面的代码
class Solution:
def diffWaysToCompute(self, input):
"""
:type input: str
:rtype: List[int]
"""
return self._diffWaysToCompute(input)
def _diffWaysToCompute(self, input):
if len(input) == 1:
return [int(input[0])]
if len(input) == 3:#bug
return [self._calc(int(input[0]), input[1], int(input[2]))]
res = list()
for i in range(1, len(input), 2):
left = self._diffWaysToCompute(input[0:i])
right = self._diffWaysToCompute(input[i+1:])
for l in left:
for r in right:
res.append(self._calc(l, input[i], r))
return res
def _calc(self, a, op, b):
return {
'+': a + b,
'-': a - b,
'*': a * b
}[op]
但是上面这个代码存在一个bug
,在len(input==3)
的时候。我们希望的结果是对于a op b
这种输入做处理,但是实际上a
和b
可能不是个位数。但是其实不止这一处存在问题,我们后面的基于步长为2
也是有问题的,所以我们需要重新整理代码。
class Solution:
def diffWaysToCompute(self, input):
"""
:type input: str
:rtype: List[int]
"""
return self._diffWaysToCompute(input)
def _diffWaysToCompute(self, input):
if input.isdigit():
return [int(input)]
res = list()
for i in range(1, len(input)):
if input[i] in "+-*":
left = self._diffWaysToCompute(input[0:i])
right = self._diffWaysToCompute(input[i+1:])
for l in left:
for r in right:
res.append(self._calc(l, input[i], r))
return res
def _calc(self, a, op, b):
return {
'+': a + b,
'-': a - b,
'*': a * b
}[op]
我们同样可以用记忆花搜索的方式优化上面的代码。
class Solution:
def diffWaysToCompute(self, input):
"""
:type input: str
:rtype: List[int]
"""
mem = dict()
return self._diffWaysToCompute(input, mem)
def _diffWaysToCompute(self, input, mem):
if input.isdigit():
return [int(input)]
if input in mem:
return mem[input]
res = list()
for i in range(1, len(input)):
if input[i] in "+-*":
left = self._diffWaysToCompute(input[0:i], mem)
right = self._diffWaysToCompute(input[i+1:], mem)
for l in left:
for r in right:
res.append(self._calc(l, input[i], r))
mem[input] = res
return res
def _calc(self, a, op, b):
return {
'+': a + b,
'-': a - b,
'*': a * b
}[op]
一个非常hacker
的写法
def diffWaysToCompute(self, input):
return [a+b if c == '+' else a-b if c == '-' else a*b
for i, c in enumerate(input) if c in '+-*'
for a in self.diffWaysToCompute(input[:i])
for b in self.diffWaysToCompute(input[i+1:])] or [int(input)]
这个代码accept
了,但是如果input
里面出现负数该怎么办?这也需要考虑。由此展开的话题就变得很复杂了,有时间的话再将这个坑补上。
扫描二维码关注公众号,回复:
4405299 查看本文章
reference:
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!