Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://leetcode.com/problems/basic-calculator/

Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .

You may assume that the given expression is always valid.

Some examples:

"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23

 

Note: Do not use the eval built-in library function.

解题思路:

这道题虽然难度为medium,但是通过率不足20%,就知道不是那么容易的了。

首先注意的是,这道题的数字不是都是一位的,所以不能想的太简单。

于是想到把数字和加减号全部push进栈,每次计算加减法,再弹出,再看运算符。后来发现越写越复杂。最后只能参考discuss里的写法。

https://leetcode.com/discuss/39553/iterative-java-solution-with-stack

其实,只需要借助三个变量,sign代表前面的运算符,num取当前数字的值,res是累计到目前为止的运算结果。

具体的运算过程:

令当前位置的字符为cur

1.cur为数字,num = num * 10 + cur,即更新当前数值。

2. cur为+或-,更新sign,同时计算前面一个轮次的运算结果,即res = res + sign * num。同时,要将sign设置为相应的+或-。

3. cur为( ,立刻将前面已经算出的结果和记录的前一个运算符入栈,暂存。

4. cur为) ,立刻计算当前运算结果。计算完后,再弹出栈顶的两个元素,进行第二波计算。栈顶第一个一定是运算符,第二个是前面存下的数字。所以遇到右括号时,要计算两次。

5. 运算到结尾,如果num不为0,再次更新res。

public class Solution {
    public int calculate(String s) {
        int sign = 1, res = 0, num = 0;
        Stack<Integer> stack = new Stack<Integer>();
        
        for(int i = 0; i < s.length(); i++) {
            char cur = s.charAt(i);
            if(cur >= '0' && cur <= '9') {
                num = num * 10 + (int)(cur - '0');
            } else if(cur == '+') {
                res += sign * num;
                num = 0;
                sign = 1;
            } else if(cur == '-') {
                res += sign * num;
                num = 0;
                sign = -1;
            }else if(cur == '(') {
                stack.push(res);
                stack.push(sign);
                res = 0;
                sign = 1;
            } else if(cur == ')') {
                res += sign * num;
                res *= stack.pop();
                res += stack.pop();
                num = 0;
            }
        }
        if(num != 0) {
            res += sign * num;
        }
        return res;
    }
}

这道题的思路,在上面的代码写出来后,是很清晰的。技巧就在于,同样是用stack,到底什么时候入栈,出栈。上面的解法里,stack里仅在于遇到左括号的时候,才会入栈的。

posted on 2015-06-26 15:37  NickyYe  阅读(220)  评论(0编辑  收藏  举报