Skip to content

Commit 7cbc537

Browse files
committed
二刷42
1 parent ec7db2f commit 7cbc537

File tree

12 files changed

+139
-6
lines changed

12 files changed

+139
-6
lines changed

README.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ TIP: **公众号的微信号是: `jikerizhi`**。__因为众所周知的原因
325325
|{source_base_url}/_0042_TrappingRainWater.java[Java]
326326
|{doc_base_url}/0042-trapping-rain-water.adoc[题解]
327327
|Hard
328-
|
328+
|单调栈
329329

330330
|{counter:codes}
331331
|{leetcode_base_url}/multiply-strings/[43. Multiply Strings]

docs/0000-23-monotonic-stack.adoc

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,46 @@
11
[#0000-23-monotonic-stack]
22
= Monotonic Stack 单调栈
33

4+
== 基本流程
5+
6+
一般会用到 `Deque` 的以下四个方法:
7+
8+
* `deque.isEmpty()`:如果deque不包含任何元素,则返回true,否则返回false。因为要栈顶元素在满足要求的时候要弹出,所以需要进行空栈判断。有些场景,可能栈一定不会空的时候,就不需要该方法进行空栈判断。
9+
* `deque.push(e)`:将元素e入栈。一定能用到该方法。
10+
* `deque.pop()`:将栈顶元素弹出,并返回当前弹出的栈顶元素。一定能用到该方法。
11+
* `deque.peek()`:获取栈顶元素,不弹出。一定能用到该方法。
12+
13+
[{java_src_attr}]
14+
----
15+
// 第一个一个单调栈
16+
Deque<Integer> stack = new LinkedList<>();
17+
// 第一个元素,直接添加
18+
stack.push(0); // 这里存的是数组下标
19+
for (int i = 1; i < nums.length; i++) {
20+
// 单调递减栈这里就是大于,即 nums[i] > nums[deque.peek()]
21+
if (nums[i] < nums[stack.peek()]) {
22+
stack.push(i);
23+
} else if (nums[i] == nums[stack.peek()]) {
24+
stack.push(i);
25+
//此处除了入栈,在有些场景下,还有可能有其他操作
26+
// ..............
27+
} else {
28+
//循环比较,直到遇到当前元素小于栈顶的元素情况,跳出循环
29+
// 单调递减栈,这里是小于,即nums[i]<nums[deque.peek()]
30+
while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) {
31+
//主要逻辑
32+
// ............
33+
// ............
34+
// 弹出栈顶元素
35+
stack.pop();
36+
} stack.push(i);
37+
}
38+
}
39+
----
40+
441
== 经典题目
542

6-
. xref:0042-trapping-rain-water.adoc[42. Trapping Rain Water]
43+
. xref:0042-trapping-rain-water.adoc[42. Trapping Rain Water] -- 这个单调栈,在中间过程加了一些操作,有意思。
744
. xref:0084-largest-rectangle-in-histogram.adoc[84. Largest Rectangle in Histogram]
845
. xref:0155-min-stack.adoc[155. Min Stack] -- 这个辅助栈也可以认为是一种单调栈。
946
. xref:0239-sliding-window-maximum.adoc[239. Sliding Window Maximum]

docs/0042-trapping-rain-water.adoc

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,40 @@ image::images/0042-00.png[{image_attr}]
1919

2020
== 解题分析
2121

22-
有点懵逼,没看太明白。
22+
image::images/0042-01.png[{image_attr}]
23+
24+
image::images/0042-02.png[{image_attr}]
25+
26+
image::images/0042-03.png[{image_attr}]
27+
28+
image::images/0042-04.png[{image_attr}]
29+
30+
image::images/0042-05.png[{image_attr}]
31+
32+
image::images/0042-06.png[{image_attr}]
2333

2434

2535
[[src-0042]]
36+
[tabs]
37+
====
38+
一刷::
39+
+
40+
--
2641
[{java_src_attr}]
2742
----
2843
include::{sourcedir}/_0042_TrappingRainWater.java[tag=answer]
2944
----
45+
--
46+
47+
二刷::
48+
+
49+
--
50+
[{java_src_attr}]
51+
----
52+
include::{sourcedir}/_0042_TrappingRainWater_2.java[tag=answer]
53+
----
54+
--
55+
====
3056

3157

3258
== 思考题
@@ -36,3 +62,5 @@ include::{sourcedir}/_0042_TrappingRainWater.java[tag=answer]
3662
== 参考资料
3763

3864
. https://leetcode.cn/problems/trapping-rain-water/solutions/9112/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-8/[42. 接雨水 - 详细通俗的思路分析,多解法^]
65+
. https://blog.csdn.net/weixin_50348837/article/details/136304458[深入理解单调栈算法,这一篇就够了^]
66+
. https://leetcode.cn/problems/trapping-rain-water/solutions/185678/trapping-rain-water-by-ikaruga/[42. 接雨水 - 单调递减栈,简洁代码,动图模拟^]

docs/images/0042-01.png

16.5 KB
Loading

docs/images/0042-02.png

15.3 KB
Loading

docs/images/0042-03.png

18 KB
Loading

docs/images/0042-04.png

17.5 KB
Loading

docs/images/0042-05.png

15.7 KB
Loading

docs/images/0042-06.png

13.4 KB
Loading

logbook/202406.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@
342342
|{doc_base_url}/0155-min-stack.adoc[题解]
343343
|复习单调栈
344344

345+
|{counter:codes}
346+
|{leetcode_base_url}/trapping-rain-water/[42. Trapping Rain Water]
347+
|{doc_base_url}/0042-trapping-rain-water.adoc[题解]
348+
|巧用单调栈
349+
345350
|===
346351

347352
截止目前,本轮练习一共完成 {codes} 道题。

src/main/java/com/diguage/algo/leetcode/_0042_TrappingRainWater.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
* Input: [0,1,0,2,1,0,1,3,2,1,2,1]
1616
* Output: 6
1717
* ----
18-
*
19-
* @author D瓜哥 · https://www.diguage.com
20-
* @since 2019-07-26 08:49
2118
*/
2219
public class _0042_TrappingRainWater {
2320
// tag::answer[]
@@ -26,6 +23,9 @@ public class _0042_TrappingRainWater {
2623
* Memory Usage: 38.3 MB, less than 91.10% of Java online submissions for Trapping Rain Water.
2724
*
2825
* Copy from: https://leetcode-cn.com/problems/trapping-rain-water/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-8/[详细通俗的思路分析,多解法 - 接雨水 - 力扣(LeetCode)]
26+
*
27+
* @author D瓜哥 · https://www.diguage.com
28+
* @since 2019-07-26 08:49
2929
*/
3030
public int trap(int[] height) {
3131
int left = 0, right = height.length - 1;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.Deque;
4+
import java.util.LinkedList;
5+
6+
/**
7+
* = 42. Trapping Rain Water
8+
*
9+
* https://leetcode.com/problems/trapping-rain-water/[Trapping Rain Water - LeetCode]
10+
*
11+
* Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
12+
*
13+
* image::https://assets.leetcode.com/uploads/2018/10/22/rainwatertrap.png[title="The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!"]
14+
*
15+
* .Example:
16+
* [source]
17+
* ----
18+
* Input: [0,1,0,2,1,0,1,3,2,1,2,1]
19+
* Output: 6
20+
* ----
21+
*/
22+
public class _0042_TrappingRainWater_2 {
23+
// tag::answer[]
24+
25+
/**
26+
* @author D瓜哥 · https://www.diguage.com
27+
* @since 2024-07-31 17:27:46
28+
*/
29+
public int trap(int[] height) {
30+
int result = 0;
31+
Deque<Integer> stack = new LinkedList<>();
32+
stack.push(0);
33+
for (int r = 1; r < height.length; r++) {
34+
// 单调递减,则将小的元素都出栈
35+
while (!stack.isEmpty() && height[stack.peek()] < height[r]) {
36+
// 递减栈,栈顶最小。与下一个元素比,栈顶小;
37+
// 上面判断条件,栈顶与当前位置元素比,也是栈顶小
38+
int mid = stack.pop();
39+
if (!stack.isEmpty()) {
40+
int l = stack.peek();
41+
// 高h 取两边最小的一个。
42+
// l 是现栈顶元素大,mid 是前栈顶元素最小,当前元素比 mid 大,
43+
// 所以,形成了一个凹槽,可以接水
44+
int h = Math.min(height[l], height[r]) - height[mid];
45+
int w = r - l - 1;
46+
int area = h * w;
47+
result += area;
48+
}
49+
}
50+
stack.push(r);
51+
}
52+
return result;
53+
}
54+
// end::answer[]
55+
56+
57+
public static void main(String[] args) {
58+
_0042_TrappingRainWater_2 solution = new _0042_TrappingRainWater_2();
59+
int r1 = solution.trap(new int[]{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1});
60+
System.out.println((r1 == 6) + " : " + r1);
61+
}
62+
}
63+

0 commit comments

Comments
 (0)