链接
https://leetcode-cn.com/problems/basic-calculator-ii/
耗时
解题:40 min
题解:25 min
题意
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
提示:
- 1 <= s.length <= 3 * 105
- s 由整数和算符 (’+’, ‘-’, ‘*’, ‘/’) 组成,中间由一些空格隔开
- s 表示一个 有效表达式
- 表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内
- 题目数据保证答案是一个 32-bit 整数
思路
根据题意可知,只有两种优先级 ‘+’, ‘-’ 和 ‘*’, ‘/’ 其中乘除的优先级更高。所以一个朴素的思想是先把带有乘除的部分计算出来,最后再一次遍历计算只有加减的表达式。
为了最后可以按下标遍历,所以我使用了双端队列,但用的是栈的思想。
设置两个栈,一个符号栈,一个数字栈。遍历字符串,如果当前是加减号就加入符号栈,如果是数字就加入数字栈,如果是乘除号,首先得到乘除号后的第一个数字和数字栈栈顶元素,并出栈,然后将栈顶元素和和这个数字乘除后入栈。一趟遍历结束后不再含有乘除法,再一趟遍历根据符号栈将数字栈中元素加减到结果中。
时间复杂度: O ( n ) O(n) O(n)
AC代码
class Solution {
public:
int calculate(string s) {
deque<int> symbol;
deque<int> nums;
if(s[0] == '-') symbol.push_back(-1);
else symbol.push_back(1);
int n = s.size();
for(int i = 0; i < n; ++i) {
if(s[i] == ' ') {
continue;
}
else if(s[i] == '+') {
symbol.push_back(1);
}
else if(s[i] == '-') {
symbol.push_back(-1);
}
else if(s[i] == '*') {
while(!(s[i] >= '0' && s[i] <= '9')) i++;
int num2 = 0;
while(s[i] >= '0' && s[i] <= '9') {
num2 = num2*10 + (s[i]-'0');
i++;
}
i--;
int num1 = nums.back();
nums.pop_back();
nums.push_back(num1*num2);
}
else if(s[i] == '/') {
while(!(s[i] >= '0' && s[i] <= '9')) i++;
int num2 = 0;
while(s[i] >= '0' && s[i] <= '9') {
num2 = num2*10 + (s[i]-'0');
i++;
}
i--;
int num1 = nums.back();
nums.pop_back();
nums.push_back(num1/num2);
}
else {
int num = 0;
while(s[i] >= '0' && s[i] <= '9') {
num = num*10 + (s[i]-'0');
i++;
}
i--;
nums.push_back(num);
}
}
int ans = 0;
for(int i = 0; i < nums.size(); ++i) {
ans += symbol[i]*nums[i];
}
return ans;
}
};