LeetCode题目(Python实现):逆波兰表达式求值

文章目录

  • 题目
    • 想法一:栈
      • 算法实现
      • 执行结果
      • 复杂度分析
      • 算法实现
      • 执行结果
    • 递归
      • 算法实现
      • 执行结果
    • 字典
      • 算法实现
      • 执行结果
    • 小结

题目

根据逆波兰表示法,求表达式的值。

有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明

  • 整数除法只保留整数部分。
  • 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例1 :

输入: ["2", "1", "+", "3", "*"]
输出: 9
解释: ((2 + 1) * 3) = 9

示例2 :

输入: ["2", "1", "+", "3", "*"]
输出: 9
解释: ((2 + 1) * 3) = 9

示例3 :

输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
输出: 22
解释: 
  ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

想法一:栈

算法实现

def evalRPN(self, tokens: List[str]) -> int:
    stack = []
    for i in tokens:
        try:
            stack.append(int(i))
        except:
            b = stack.pop()
            a = stack.pop()
            if i == "+":
                stack.append(a + b)
            elif i == "-":
                stack.append(a - b)
            elif i == "*":
                stack.append(a * b)
            elif i == "/":
                stack.append(int(a / b))
    return stack.pop()

执行结果

执行结果 : 通过
执行用时 : 52 ms, 在所有 Python3 提交中击败了83.22%的用户
内存消耗 : 13.9 MB, 在所有 Python3 提交中击败了5.26%的用户
LeetCode题目(Python实现):逆波兰表达式求值_第1张图片

复杂度分析

  • 时间复杂度:O(N),这里 N 是字符串数量。
  • 空间复杂度:O(N)

算法实现

# 较为简洁,但比较慢,新函数eval()函数用来执行一个字符串表达式,并返回表达式的值。
def evalRPN(self, tokens: List[str]) -> int:
    stack = []
    for i in tokens:
        if i in {'+', '-', '*', '/'}:
            a, b = stack.pop(), stack.pop()
            stack.append(str(int(eval(b + i + a))))
        else:
            stack.append(i)
    return int(stack[-1])

执行结果

LeetCode题目(Python实现):逆波兰表达式求值_第2张图片

递归

算法实现

def evalRPN(self, tokens: List[str]) -> int:
    t, f = tokens.pop(), self.evalRPN
    if t in '+-*/':
        b, a = f(tokens), f(tokens)
        t = eval('a' + t + 'b')
    return int(t)

执行结果

LeetCode题目(Python实现):逆波兰表达式求值_第3张图片

字典

算法实现

def evalRPN(self, tokens: List[str]) -> int:
    tmp = []
    op = {
        "+": lambda x, y: x + y,
        "-": lambda x, y: y - x,
        "*": lambda x, y: x * y,
        "/": lambda x, y: int(y / x)
    }
    for t in tokens:
        if t in op:
            r = tmp.append(op[t](tmp.pop(), tmp.pop()))
        else:
            tmp.append(int(t))
    return tmp.pop()

执行结果

LeetCode题目(Python实现):逆波兰表达式求值_第4张图片

小结

总的来说首先想到的是利用栈,不同做法的区别在于如何处理运算符的问题;然后说到栈肯定会想到递归,前者是后者的基本原理,所以可以互相转化,但是递归在这道题有些晦涩难懂,需要动手试试。

题虽简单,但是又学到了一些东西,比如eval()函数是用来执行一个字符串表达式,并返回表达式的值(再次感叹Python的强大);而且学到了用字典也可以储存lambda函数,是个不错的方法。

你可能感兴趣的:(LeetCode题目)