力扣 227. 基本计算器 II

题目说明

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

整数除法仅保留整数部分。

  • 1 <= s.length <= 3 * 105
  • s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
  • s 表示一个 有效表达式
  • 表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1]
  • 题目数据保证答案是一个 32-bit 整数

示例

例1

1
2
输入:s = "3+2*2"
输出:7

例2

1
2
输入:s = " 3/2 "
输出:1

示例 3:

1
2
输入:s = " 3+5 / 2 "
输出:5

笔者理解

此题是一道字符串算法问题,在力扣题库中被定义为中等题。

解法

当笔者阅读完此题后,发现此题运用栈比较合适,当我们遍历到一个数时,就将其插入栈中(需要注意的是此题中可以会出现大于9的数,也就是不止一位数),然后因为此题只有四则运算,所以遇见乘除直接运算(将当前数与栈顶元素进行运算并置换即可),遇见减号将其取负放入栈,最后栈中只剩下多个数,累加输出即可让我们来看看具体如何实现的吧。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public int calculate(String s) {
int result = 0;
Deque <Integer>stack = new LinkedList<Integer>();

char symbol = '+';
//预设第一个符号为'+'

char temp;
//代表字符串中的各个字节

int num = 0;
//存储字符串中的各个数组

for(int i = 0; i < s.length(); i++) {
temp = s.charAt(i);
//取第i个字节

if(temp >= '0') {
//如果当前字节为数字
//因为+、-、*、/以及空格的asc码都小于0的asc码

num = num*10 - '0' + temp;
//先减后加预防越界
//此处的'0'和temp运算的都是对应的asc码
}
if((temp < '0' && temp != ' ')|| i == s.length()-1) {
//当当前字节是符号且不为空格或者是最后一个字节时
switch(symbol){
//根据当前数字之前的符号进行操作

case '+': stack.offer(num);break;
//加号,直接入栈(在此为加入双端对列尾部)

case '-': stack.offer(-num);break;
//减号转化为负数,直接入栈(在此为加入双端对列尾部)

case '*': stack.offer(stack.pollLast()*num);break;
case '/': stack.offer(stack.pollLast()/num);break;
//乘除号,分别将当前数与栈顶(在此处为双端队列的尾部)元素(需要进行弹出也就是取出并删除)进行乘除运算
}
symbol = temp;
num = 0;
//置换符号
//数字归零
}
}
while(!stack.isEmpty()){
result+=stack.poll();
//乘除运算都进行后,剩下的都是正数和负数,累加即可
}
return result;
}

时间和空间效率都还行,可见此解法还比较适合此题;

image.png

总结

本题是今天的每日一题,难度是为中等,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。