题意整理
- 给定一个逆波兰表达式,表达式中仅包含加减乘除和数字。
- 求表达式的值。
方法一(栈)
1.解题思路
逆波兰表达式求值的过程总是先列出运算符前面两个数字,然后将这两个数字进行相应运算,得到一个新的数字,这个数又与后面的数进行相应运算,直到结束。
所以,可以先新建一个栈,当遇到数字时,直接压入栈中,遇到运算符时,先取出栈顶的两个数字,进行相应运算,再压回栈中。最后栈中剩下的那个元素即是表达式的值。
图解展示:
2.代码实现
import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param tokens string字符串一维数组 
     * @return int整型
     */
    public int evalRPN (String[] tokens) {
        //新建一个栈
        LinkedList<String> stack=new LinkedList<>();
        //遍历tokens数组
        for(String token:tokens){
            //如果是数字,直接压入栈中
            if(!token.equals("+")&&!token.equals("-")&&!token.equals("*")&&!token.equals("/")){
                stack.push(token);
            }
            else{
                //如果是加减乘除,均需要两次弹出栈顶元素,再进行相应计算
                int val1=Integer.parseInt(stack.pop());
                int val2=Integer.parseInt(stack.pop());
                //如果是加号,将两个弹出的数相加,再压入栈中
                if(token.equals("+")){
                    stack.push(String.valueOf(val2+val1));
                }
                //如果是减号,将两个弹出的数相减,再压入栈中
                else if(token.equals("-")){
                    stack.push(String.valueOf(val2-val1));
                }
                //如果是乘号,将两个弹出的数相乘,再压入栈中
                else if(token.equals("*")){
                    stack.push(String.valueOf(val2*val1));
                }
                //如果是除号,将两个弹出的数相除,再压入栈中
                else{
                    stack.push(String.valueOf(val2/val1));
                }
            }
        }
        return Integer.parseInt(stack.peek());
    }
}
3.复杂度分析
- 时间复杂度:需要遍历整个字符串数组,所以时间复杂度是。
- 空间复杂度:最坏情况下,总共有个数压入栈中,所以至多需要额外大小为的栈,所以空间复杂度为。
方法二(数组模拟栈)
1.解题思路
与方法一的思路差不多,不过可以考虑使用数组来模拟栈。
假设逆波兰表达式中总共有n个元素,则n必定是奇数,并且数字的个数恰好比运算符个数多1。因为起初只有1个数字时,每加一个运算符,必定会加1个数字,依次类推,数字恰好比运算符多1。所以数字个数有个,运算符个数有个。用栈模拟的过程中,每次遇到数字,直接压入栈中,栈的容量会加1,遇到运算符时,先弹出两个元素,做运算后再压入栈中,栈的容量会减1。最坏情况下,数字全在前面,运算符全在后面,栈的容量最多达到。
我们初始化arr数组的容量为。用一个变量index指向栈顶的位置,index为-1表示栈容量为0。当压栈时,index加1,再将元素赋给当前位置,弹栈时,index减1即可。
2.代码实现
import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param tokens string字符串一维数组 
     * @return int整型
     */
    public int evalRPN (String[] tokens) {
        int n=tokens.length;
        //定义数组arr,用于模拟栈
        int[] arr=new int[(n+1)/2];
        //指向栈顶位置
        int index=-1;
        for(String token:tokens){
            //如果是数字,直接index加1,并将数字赋值到当前位置
            if(!token.equals("+")&&!token.equals("-")&&!token.equals("*")&&!token.equals("/")){
                arr[++index]=Integer.parseInt(token);
            }
            else{
                //如果是加号,index减1,并将当前位置数字加上后一位的数字
                if(token.equals("+")){
                    index--;
                    arr[index]+=arr[index+1];
                }
                //如果是减号,index减1,并将当前位置数字减去后一位的数字
                else if(token.equals("-")){
                    index--;
                    arr[index]-=arr[index+1];
                }
                //如果是乘号,index减1,并将当前位置数字乘以后一位的数字
                else if(token.equals("*")){
                    index--;
                    arr[index]*=arr[index+1];
                }
                //如果是除号,index减1,并将当前位置数字除以后一位的数字
                else{
                    index--;
                    arr[index]/=arr[index+1];
                }
            }
        }
        return arr[0];
    }
}
3.复杂度分析
- 时间复杂度:需要遍历整个字符串数组,所以时间复杂度是。
- 空间复杂度:需要额外大小为的arr数组,所以空间复杂度为。

 京公网安备 11010502036488号
京公网安备 11010502036488号