力扣150(java)-逆波兰表达式求值(中等)

题目:

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

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

注意 两个整数之间的除法只保留整数部分。

可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

 示例 1:

输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:

输入:tokens = ["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
 

提示:

  • 1 <= tokens.length <= 104
  • tokens[i] 是一个算符("+"、"-"、"*" 或 "/"),或是在范围 [-200, 200] 内的一个整数

逆波兰表达式:

逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。

  • 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
  • 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
  • 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中

来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

1.利用栈后进先出的特点进行模拟:

  • 遍历输入的字符串;
  • 遇到整数时,直接将整数压入栈中;
  • 遇到操作符(+ - * /),就从栈顶依次弹出两个操作数与此时的操作符进行运算,并将运算结果作为操作数压入栈中,进行下一轮循环;
  • 数组遍历完后,栈顶元素就是表达式的值,直接弹出栈顶元素进行返回即可。

代码:

 1 class Solution {
 2     public int evalRPN(String[] tokens) {
 3         Deque<Integer> stack = new ArrayDeque<>();
 4         for(String s : tokens){
 5             if(s.equals("+")){
 6                int num1 = stack.pop();
 7                int num = num1 +stack.pop();
 8                stack.push(num);
 9             }else if(s.equals("-")){
10                 int num1 = stack.pop();
11                 int num = stack.pop() - num1;
12                 stack.push(num);
13             }else if(s.equals("*")){
14                 int num1 = stack.pop();
15                 int num = num1 * stack.pop();
16                 stack.push(num);
17             }else if(s.equals("/")){
18                 int num1 = stack.pop();
19                 int num = stack.pop() / num1;
20                 stack.push(num);
21             }else{
22                 stack.push(Integer.parseInt(s));
23             }
24         }
25        return stack.pop();
26     }
27 }

今天终于自己独立的看题目解出一道题并通过啦~

2023-05-24:

 1 class Solution {
 2     public int evalRPN(String[] tokens) {
 3       Stack<Integer> stack = new Stack<>();
 4       for (String s : tokens){
 5           if (s.equals("+")){
 6               stack.push(stack.pop() + stack.pop());
 7           }else if (s.equals("-")){
 8               stack.push(-stack.pop() + stack.pop());
 9           }else if (s.equals("*")){
10               stack.push(stack.pop() * stack.pop());
11           }else if (s.equals("/")){
12               int temp1 = stack.pop();
13               int temp2 = stack.pop();
14               stack.push(temp2 / temp1);
15           }else {
16               stack.push(Integer.valueOf(s));
17           }
18         }
19         return stack.pop();
20     }
21 }

小知识:

Integer.valueOf(s)在Integer.parseInt(s)的计算的基础上,将int类型的数值转换成了Integer类型,就是基本类型的包装类型是引用类型。所以单单为了得到一个int值,就用Integer.parseInt(s)就行了。如果为了得到包装类型就用Integer.valueOf(s)。毕竟缓存了一部分数值,可以加强点儿性能。本题栈中存放是类型就是Integer,故这里需要使用Integer.valueOf(s)。

2.利用数组存放操作数来模拟栈实现:

思路跟上面一致,有几个可以改善的地方:

  • 数组的长度可以设置成  tokens.length / 2 + 1,因为每两个操作数只需要一个操作符,操作数只需要 tokens.length / 2 + 1个长度就可以,例如[4,13,5]三个操作数只需要两个位置就可以了。
  • 使用switc..case 代替 if...else if ...else 效率更优化

代码:

 1 class Solution {
 2     public int evalRPN(String[] tokens) {
 3        int[] numStack = new int[tokens.length /2 + 1];
 4        int index = 0;
 5        for(String s : tokens){
 6            switch(s){
 7                case "+":
 8                     numStack[index - 2] += numStack[--index];
 9                     break;
10                 case "-":
11                     numStack[index - 2] -= numStack[--index];
12                     break;
13                 case "*":
14                     numStack[index - 2] *= numStack[--index];
15                     break;
16                 case "/":
17                     numStack[index - 2] /= numStack[--index];
18                     break;
19                 default:
20                     numStack[index++] = Integer.parseInt(s);
21            }
22         }
23         return numStack[0];
24     }
25 }

posted on 2022-09-02 10:19  我不想一直当菜鸟  阅读(47)  评论(0编辑  收藏  举报