逆波兰表达式求值(150. 逆波兰表达式求值&&剑指 Offer II 036. 后缀表达式)

题目:

 

 逆波兰表达式:

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

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

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

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

思路:

【1】这道题本身就是比较简单的,根据波兰表达式的定义其实借助辅助空间更容易理解,而且时间复杂度和空间复杂度都为O(N)

【2】基于此其实还可以进一步优化就是将空间复杂度降低为O(1),需要两个指针和两个存储变量,然后在本身的数组上变动。

代码展示:

//常规做法
//执行用时:7 ms, 在所有 Java 提交中击败了20.65%的用户
//内存消耗:41.1 MB, 在所有 Java 提交中击败了55.71%的用户
class Solution {
    public int evalRPN(String[] tokens) {
        if (tokens.length == 1 ){
            return Integer.parseInt(tokens[0]);
        }
        Stack<Integer> stack = new Stack<>();
        int a,b;
        for (int i = 0; i<tokens.length;i++){
            if (!"+".equals(tokens[i]) && !"-".equals(tokens[i]) && !"*".equals(tokens[i]) && !"/".equals(tokens[i])){
                stack.add(Integer.parseInt(tokens[i]));
            }else {
                b = Objects.requireNonNull(stack.pop());
                a = Objects.requireNonNull(stack.pop());
                switch (tokens[i]){
                    case "+":
                        stack.add(a+b);
                        break;
                    case "-":
                        stack.add(a-b);
                        break;
                    case "*":
                        stack.add(a*b);
                        break;
                    case "/":
                        stack.add(a/b);
                        break;
                    default:
                        break;
                }
            }
        }
        return stack.pop();
    }
}

//用数组替换栈数据结构的做法
//执行用时:4 ms, 在所有 Java 提交中击败了96.23%的用户
//内存消耗:41.2 MB, 在所有 Java 提交中击败了42.76%的用户
class Solution {
    public int evalRPN(String[] tokens) {
        if (tokens.length == 1 ){
            return Integer.parseInt(tokens[0]);
        }
        int[] stack = new int[tokens.length];
        int a,b,index = 0;

        for (int i = 0; i<tokens.length;i++){
            if (!"+".equals(tokens[i]) && !"-".equals(tokens[i]) && !"*".equals(tokens[i]) && !"/".equals(tokens[i])){
                stack[index++] = Integer.parseInt(tokens[i]);
            }else {
                b = stack[--index];
                a = stack[--index];
                switch (tokens[i]){
                    case "+":
                        stack[index++] = a + b;
                        break;
                    case "-":
                        stack[index++] = a - b;
                        break;
                    case "*":
                        stack[index++] = a * b;
                        break;
                    case "/":
                        stack[index++] = a / b;
                        break;
                    default:
                        break;
                }
            }
        }
        return stack[--index];
    }
}

所以空间复杂度为O(1)的做法:

提交完,看了时间反而比用int数组的花的多,而且消耗内存也没有降下了,估计是int和string两个花了双倍内存,笑死了,想法是好的,但是没有什么卵用。

//不借助辅助空间的做法
//执行用时:5 ms, 在所有 Java 提交中击败了94.04%的用户
//内存消耗:41.5 MB, 在所有 Java 提交中击败了15.26%的用户
class Solution {
    public int evalRPN(String[] tokens) {
        if (tokens.length == 1 ){
            return Integer.parseInt(tokens[0]);
        }
        int a,b,index = 0;

        for (int i = 0; i<tokens.length;i++){
            if (!"+".equals(tokens[i]) && !"-".equals(tokens[i]) && !"*".equals(tokens[i]) && !"/".equals(tokens[i])){
                tokens[index++] = tokens[i];
            }else {
                b = Integer.parseInt(tokens[--index]);
                a = Integer.parseInt(tokens[--index]);
                switch (tokens[i]){
                    case "+":
                        tokens[index++] = (a + b)+"";
                        break;
                    case "-":
                        tokens[index++] = (a - b)+"";
                        break;
                    case "*":
                        tokens[index++] = (a * b)+"";
                        break;
                    case "/":
                        tokens[index++] = (a / b)+"";
                        break;
                    default:
                        break;
                }
            }
        }
        return Integer.parseInt(tokens[--index]);
    }
}

 

posted @ 2023-03-16 14:24  忧愁的chafry  阅读(22)  评论(0编辑  收藏  举报