Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6403581

Browse filesBrowse files
committed
Create stack_queue.md
1 parent 4e9b53d commit 6403581
Copy full SHA for 6403581

File tree

Expand file treeCollapse file tree

1 file changed

+210
-0
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+210
-0
lines changed

‎data_structure/stack_queue.md

Copy file name to clipboard
+210Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# 栈和队列
2+
3+
## 简介
4+
5+
栈的特点是后入先出
6+
7+
根据这个特点可以临时保存一些数据,之后用到依次再弹出来,常用于树的非递归遍历、 DFS 深度搜索。
8+
9+
队列常用于BFS广度搜索,很少单独考察。
10+
11+
## 基本应用
12+
13+
### 逆波兰表达式求值
14+
15+
> [150. 逆波兰表达式求值](https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/)
16+
>
17+
> **波兰表达式计算** > **输入:** `["2", "1", "+", "3", "*"]` > **输出:** 9
18+
>
19+
> **解释:** `((2 + 1) * 3) = 9`
20+
21+
```java
22+
public int evalRPN(String[] tokens) {
23+
Stack<Integer> stack = new Stack<>();
24+
for (String s : tokens) {
25+
if ("+".equals(s) || "-".equals(s) || "*".equals(s) || "/".equals(s)) {
26+
int a = stack.pop();
27+
int b = stack.pop();
28+
if ("+".equals(s)) stack.push(b + a);
29+
else if ("-".equals(s)) stack.push(b - a);
30+
else if ("*".equals(s)) stack.push(b * a);
31+
// 注意:b为被除数,a为除数
32+
else if ("/".equals(s)) stack.push(b / a);
33+
} else {
34+
// 转为数字
35+
stack.push(Integer.parseInt(s));
36+
}
37+
}
38+
return stack.pop();
39+
}
40+
```
41+
42+
### 有效的括号
43+
44+
> [20. 有效的括号](https://leetcode-cn.com/problems/valid-parentheses/)
45+
>
46+
> 给定一个只包括 `'('``')'``'{'``'}'``'['``']'` 的字符串 `s` ,判断字符串是否有效。
47+
>
48+
> 有效字符串需满足:
49+
>
50+
> 1. 左括号必须用相同类型的右括号闭合。
51+
> 2. 左括号必须以正确的顺序闭合。
52+
53+
```java
54+
public boolean isValid(String s) {
55+
Stack<Character> stack = new Stack<>();
56+
for (char c : s.toCharArray()) {
57+
if (c == '(') stack.push(')');
58+
else if (c == '[') stack.push(']');
59+
else if (c == '{') stack.push('}');
60+
else if (stack.isEmpty() || c != stack.pop()) {
61+
return false;
62+
}
63+
}
64+
return stack.isEmpty();
65+
}
66+
```
67+
68+
## 单调栈
69+
70+
单调栈:栈内元素保持单调递增或单调递减的栈
71+
72+
**(以单调递增栈为例)**
73+
74+
入栈规则:
75+
76+
- 新元素比栈顶元素小:直接入栈
77+
78+
- 新元素比栈顶元素大:弹出栈内元素知道栈顶比新元素小(或空栈)
79+
80+
出栈意义:
81+
82+
- 需要出栈时,入栈的新元素是出栈元素右方第一个比出栈元素小的元素
83+
84+
- 出栈后,新的栈顶是出栈元素左侧最大的数
85+
86+
技巧:最后添加一个值为0的哨兵节点,可以在最后强制所有元素出栈。
87+
88+
以下分别使用了单调递增栈和单调递减栈
89+
90+
### 柱状图中最大的矩形
91+
92+
> [84. 柱状图中最大的矩形](https://leetcode-cn.com/problems/largest-rectangle-in-histogram/)
93+
>
94+
> 给定 *n* 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
95+
>
96+
> 求在该柱状图中,能够勾勒出来的矩形的最大面积。
97+
98+
```java
99+
public int largestRectangleArea(int[] heights) {
100+
if (heights.length == 0) {
101+
return 0;
102+
}
103+
Stack<Integer> stack = new Stack<>();
104+
int max = 0;
105+
// 当前高度小于栈,则将栈内元素都弹出计算面积
106+
for (int i = 0; i <= heights.length; i++) {
107+
int cur = 0;
108+
if (i < heights.length) {
109+
cur = heights[i];
110+
}
111+
while (stack.size() != 0 && cur <= heights[stack.peek()]) {
112+
int index = stack.pop();
113+
int h = heights[index];
114+
// 计算宽度
115+
int w = i;
116+
if (stack.size() != 0) {
117+
int peek = stack.peek();
118+
w = i - peek - 1;
119+
}
120+
max = Math.max(max, h * w);
121+
}
122+
// 记录索引即可获取对应元素
123+
stack.push(i);
124+
}
125+
return max;
126+
}
127+
```
128+
129+
### 接雨水
130+
131+
> [42. 接雨水](https://leetcode-cn.com/problems/trapping-rain-water/)
132+
>
133+
> 给定 *n* 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
134+
135+
```java
136+
public int trap(int[] height) {
137+
int sum = 0;
138+
Stack<Integer> stack = new Stack<>();
139+
int current = 0;
140+
while (current < height.length) {
141+
//如果栈不空并且当前指向的高度大于栈顶高度就一直循环
142+
while (!stack.empty() && height[current] > height[stack.peek()]) {
143+
int h = height[stack.peek()]; //取出要出栈的元素
144+
stack.pop(); //出栈
145+
if (stack.empty()) { // 栈空就出去
146+
break;
147+
}
148+
int distance = current - stack.peek() - 1; //两堵墙之前的距离。
149+
int min = Math.min(height[stack.peek()], height[current]);
150+
sum = sum + distance * (min - h);
151+
}
152+
stack.push(current); //当前指向的墙入栈
153+
current++; //指针后移
154+
}
155+
return sum;
156+
}
157+
```
158+
159+
## 设计类问题
160+
161+
> [2. 用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks/)
162+
163+
```java
164+
class MyQueue {
165+
166+
private Stack<Integer> stack1 = new Stack<>();
167+
private Stack<Integer> stack2 = new Stack<>();
168+
169+
/** Initialize your data structure here. */
170+
public MyQueue() {
171+
172+
173+
}
174+
175+
/** Push element x to the back of queue. */
176+
public void push(int x) {
177+
while (! stack2.isEmpty()) {
178+
int val = stack2.pop();
179+
stack1.push(val);
180+
}
181+
stack1.push(x);
182+
}
183+
184+
/** Removes the element from in front of queue and returns that element. */
185+
public int pop() {
186+
while (! stack1.isEmpty()) {
187+
int val = stack1.pop();
188+
stack2.push(val);
189+
}
190+
if (stack2.isEmpty()) return -1;
191+
return stack2.pop();
192+
}
193+
194+
/** Get the front element. */
195+
public int peek() {
196+
while (! stack1.isEmpty()) {
197+
int val = stack1.pop();
198+
stack2.push(val);
199+
}
200+
if (stack2.isEmpty()) return -1;
201+
return stack2.peek();
202+
}
203+
204+
/** Returns whether the queue is empty. */
205+
public boolean empty() {
206+
return stack1.isEmpty() && stack2.isEmpty();
207+
}
208+
}
209+
```
210+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.