Skip to content

Commit 8d07114

Browse files
committed
224.基本计算器,双栈
1 parent 0083f08 commit 8d07114

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

leetcode_Java/DoneTitle.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
215. 数组中的第K个最大元素
104104
216. 组合总和 III
105105
221. 最大正方形
106+
224. 基本计算器
106107
226. 翻转二叉树
107108
232. 用栈实现队列
108109
234. 回文链表

leetcode_Java/DoneType.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
151. 颠倒字符串中的单词(分割反转,双指针,双端队列)
206206
165. 比较版本号(双指针,字符串分割)
207207
208. 实现 Trie (前缀树)
208+
224. 基本计算器(双栈)
208209
394. 字符串解码(栈)
209210
415. 字符串相加(模拟相加)
210211
438. 找到字符串中所有字母异位词(滑动窗口,双指针)

leetcode_Java/Solution0224.java

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// 224. 基本计算器
2+
3+
4+
/*
5+
双栈:
6+
1、使用两个栈,numsStack 存放数字,opsStack 存放操作符
7+
2、预处理:
8+
1)由于第一个数可能是负数,为了减少边界判断,先往 numsStack 添加一个 0
9+
2)输入中不存在两个连续的操作符,为防止 () 内出现的首个字符为运算符,将所有空格去掉,将 (- 替换为 (0- ,(+ 替换为 (0+
10+
3、遍历字符串中的字符
11+
1)遇到 ( 时,则存入操作符栈
12+
2)遇到 ) 时,
13+
① 当操作符栈 不为空 且 栈顶不是左括号时,取出两个数字和操作符进行计算,并将计算结果存入数字栈
14+
② 直到遇到左括号,从操作符栈 出栈
15+
3)遇到数字时,继续遍历获取连续的数字,并将字符串转化成整型类型数字,最后数字存入数字栈
16+
4)遇到操作符 +、- 时,
17+
① 如果前一字符是左括号,要先将0存入数字栈,表示 (0- 或 (0+ ,才能进行计算
18+
② 当操作符栈 不为空 且 栈顶不是左括号时,取出两个数字和操作符进行计算,并将计算结果存入数字栈
19+
③ 将当前操作符存入 操作符栈
20+
4、操作符栈仍不为空时,取出两个数字和操作符进行计算,并将计算结果存入数字栈,最终返回数字栈顶值
21+
5、计算的时机:
22+
1)当前字符为 ) ,操作符栈顶字符为 (,说明括号内的数字计算完了,可以结束了
23+
当前字符为 +、- ,操作符栈顶字符为 (,说明括号内的数字只有一个,还不能计算
24+
所以遇到 )、+、- 时,操作符栈 不为空 且 栈顶不是 ( 时才能计算
25+
2)遇到 )、+、- 时,才会计算前一操作符的结果,然后将 (出操作符栈 或 +、-入操作符栈
26+
3)字符串遍历完后,操作符栈会不为空,因为 遇到新的操作符才会计算旧的操作符 和 受到(的限制 导致前面的没有计算,但只剩 +、-,所以可以直接计算
27+
*/
28+
class Solution {
29+
public int calculate(String s) {
30+
Deque<Character> opsStack = new ArrayDeque<>();
31+
Deque<Integer> numsStack = new ArrayDeque<>();
32+
numsStack.push(0);
33+
s = s.replaceAll(" ", "");
34+
int n = s.length();
35+
char[] charArray = s.toCharArray();
36+
for (int i = 0; i < n; i++) {
37+
char c = charArray[i];
38+
if (c == '(') {
39+
opsStack.push(c);
40+
} else if (c == ')') {
41+
while (!opsStack.isEmpty() && opsStack.peek() != '(') {
42+
cal(numsStack, opsStack);
43+
}
44+
opsStack.pop();
45+
} else if (Character.isDigit(c)) {
46+
int j = i, num = 0;
47+
while (j < n && Character.isDigit(charArray[j])) {
48+
num = num * 10 + charArray[j++] - '0';
49+
}
50+
numsStack.push(num);
51+
i = j - 1;
52+
} else {
53+
if (i > 0 && charArray[i - 1] == '(') {
54+
numsStack.push(0);
55+
}
56+
while (!opsStack.isEmpty() && opsStack.peek() != '(') {
57+
cal(numsStack, opsStack);
58+
}
59+
opsStack.push(c);
60+
}
61+
}
62+
while (!opsStack.isEmpty()) {
63+
cal(numsStack, opsStack);
64+
}
65+
return numsStack.peek();
66+
}
67+
68+
private void cal(Deque<Integer> numsStack, Deque<Character> opsStack) {
69+
if (numsStack.isEmpty() || numsStack.size() < 2 || opsStack.isEmpty()) {
70+
return;
71+
}
72+
int b = numsStack.pop(), a = numsStack.pop();
73+
char op = opsStack.pop();
74+
numsStack.push(op == '+' ? a + b : a - b);
75+
}
76+
}
77+
78+
79+
/*
80+
ArrayDeque使用不同的api
81+
*/
82+
class Solution {
83+
public int calculate(String s) {
84+
Deque<Character> opsQueue = new ArrayDeque<>();
85+
Deque<Integer> numsQueue = new ArrayDeque<>();
86+
numsQueue.addLast(0);
87+
s = s.replaceAll(" ", "");
88+
int n = s.length();
89+
char[] charArray = s.toCharArray();
90+
for (int i = 0; i < n; i++) {
91+
char c = charArray[i];
92+
if (c == '(') {
93+
opsQueue.addLast(c);
94+
} else if (c == ')') {
95+
while (!opsQueue.isEmpty() && opsQueue.peekLast() != '(') {
96+
cal(numsQueue, opsQueue);
97+
}
98+
opsQueue.pollLast();
99+
} else if (Character.isDigit(c)) {
100+
int j = i, num = 0;
101+
while (j < n && Character.isDigit(charArray[j])) {
102+
num = num * 10 + charArray[j++] - '0';
103+
}
104+
numsQueue.addLast(num);
105+
i = j - 1;
106+
} else {
107+
if (i > 0 && charArray[i - 1] == '(') {
108+
numsQueue.addLast(0);
109+
}
110+
while (!opsQueue.isEmpty() && opsQueue.peekLast() != '(') {
111+
cal(numsQueue, opsQueue);
112+
}
113+
opsQueue.addLast(c);
114+
}
115+
}
116+
while (!opsQueue.isEmpty()) {
117+
cal(numsQueue, opsQueue);
118+
}
119+
return numsQueue.peekLast();
120+
}
121+
122+
private void cal(Deque<Integer> numsQueue, Deque<Character> opsQueue) {
123+
if (numsQueue.isEmpty() || numsQueue.size() < 2 || opsQueue.isEmpty()) {
124+
return;
125+
}
126+
int b = numsQueue.pollLast(), a = numsQueue.pollLast();
127+
char op = opsQueue.pollLast();
128+
numsQueue.addLast(op == '+' ? a + b : a - b);
129+
}
130+
}

0 commit comments

Comments
 (0)