Skip to content

Commit 9b6091b

Browse files
author
liguanliang1
committed
feat: water-problem
1 parent 143025e commit 9b6091b

File tree

6 files changed

+400
-242
lines changed

6 files changed

+400
-242
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import LinkedList from '../link-list/LinkedList'
2+
3+
4+
// 积水问题,使用单调栈的思想
5+
class Solution42 {
6+
trap(height) {
7+
const stack = new LinkedList();
8+
// 最少也需要3个柱子才能积水,否则直接返回0
9+
if (height.length < 3) return 0;
10+
11+
let res = 0;
12+
for (let i = 0; i < height.length; i++) {
13+
// 当栈不为空,且不满足递减关系 弹栈并记录弹出元素下标,用于计算积水高度
14+
while (!stack.isEmpty() && height[i] > height[stack.getLast()]) {
15+
let temp = stack.deleteTail();
16+
// 当有重复连续值时都弹出
17+
while (!stack.isEmpty() && height[temp] == height[stack.getLast()]) {
18+
stack.deleteTail();
19+
}
20+
//计算积水深度
21+
if (!stack.isEmpty()) {
22+
// 计算宽度
23+
let width = i - stack.getLast() - 1;
24+
// 计算高度
25+
let high = Math.min(height[i] - height[temp], height[stack.getLast()] - height[temp]);
26+
// System.out.println(i + " " + width + " " + high + " " + temp);
27+
res += high * width;
28+
}
29+
}
30+
stack.append(i);
31+
// System.out.println();
32+
}
33+
34+
return res;
35+
}
36+
}
37+
38+
const s = new Solution42()
39+
const result= s.trap([4,2,0,3,2,5])
40+
console.log('water-problem',result)
41+
// // 按层计算,负责度较高可能会超时
42+
// class Solution42_byLayer {
43+
// public let trap(let[] height) {
44+
// let res = 0, max = 0;
45+
// for (let i = 0; i < height.length; i++) {
46+
// max = Math.max(height[i], max);
47+
// }
48+
49+
// // 按层计算
50+
// for (let i = 1; i <= max; i++) {
51+
// boolean flag = false;
52+
// let ceng = 0;
53+
// for (let j = 0; j < height.length; j++) {
54+
// // 如果有小于i的且左边有>=i的则此处可以存水
55+
// if (flag && height[j] < i) {
56+
// ceng++;
57+
// }
58+
// // 可挡住水的墙把flag设置为True 把ceng加到总数上再置零计算下一个积水处
59+
// if (height[j] >= i) {
60+
// flag = true;
61+
// res += ceng;
62+
// ceng = 0;
63+
// }
64+
// }
65+
// }
66+
67+
// return res;
68+
// }
69+
// }
70+
71+
72+
// // 按列计算,第一列和最后一列不可能存水直接跳过 1~height.length-1
73+
// class Solution42_byClo {
74+
// public let trap(let[] height) {
75+
// let res = 0, max = 0;
76+
77+
// // 第一列和最后一列不可能存水直接跳过 1~height.length-1
78+
// for (let i = 1; i < height.length - 1; i++) {
79+
// let left = 0, right = 0, min = 0;
80+
81+
// // 计算左边最大值
82+
// for (let j = i - 1; j >= 0; j--) {
83+
// left = Math.max(left, height[j]);
84+
// }
85+
86+
// //计算右侧最大值
87+
// for (let j = i + 1; j < height.length; j++) {
88+
// right = Math.max(right, height[j]);
89+
// }
90+
91+
// min = Math.min(right, left);
92+
93+
// // i列积水深度
94+
// let deep = min - height[i];
95+
// if (deep > 0) {
96+
// res += deep;
97+
// }
98+
// }
99+
100+
// return res;
101+
// }
102+
// }
103+
104+
// // 双指针法
105+
// // 设置两个指针向中间移动,用maxLeft、maxRight分别记录左侧和右侧的最值
106+
// // 若maxLeft < maxRight 则以左侧为依据,否则以右侧为依据
107+
// // 以左侧为依据时候,当前左指针指向元素height[left]>=maxLeft 则该地方不能积水,left++向右移动。否则res += maxLeft - height[left]
108+
// // 以右侧为依据时候,当前右指针指向元素height[right]>=maxRight 则改地方不能积水。否则res += maxRight - height[left]
109+
// class Solution42_byDoublePointer {
110+
// public let trap(let[] height) {
111+
// let res = 0, maxLeft = height[0], max_Right = height[height.length - 1], left = 0, right = height.length - 1;
112+
// while (left <= right) {
113+
// // 如果左侧比较小,则以左侧为准,判断height[left]处是否积水
114+
// if (maxLeft < max_Right) {
115+
// // 如果左侧最大值比当前左指针位置大则可以积水
116+
// if (height[left] < maxLeft) {
117+
// res += maxLeft - height[left];
118+
// } else { // 否则该位置不能积水,因为其比左侧最大高度低 不能积水
119+
// maxLeft = Math.max(height[left], maxLeft);
120+
121+
// }
122+
// left++;
123+
// } else { // 此时右侧高度比较小,判断右侧位置情况
124+
// // 此时 height[right] 比较小可以积水
125+
// if (height[right] < max_Right) {
126+
// res += max_Right - height[right];
127+
// } else { // 此时不能积水
128+
// max_Right = Math.max(max_Right, height[right]);
129+
130+
// }
131+
// right--; // 指针左移动
132+
// }
133+
134+
// }
135+
// return res;
136+
// }
137+
// }
138+
139+
// public class LeetCode42 {
140+
// @Test
141+
// public void test() {
142+
// // let[] height = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
143+
// let [] height = { 2, 0, 2};
144+
// System.out.println(new Solution42().trap(height));
145+
// System.out.println(new Solution42_byLayer().trap(height));
146+
// System.out.println(new Solution42_byClo().trap(height));
147+
// System.out.println(new Solution42_byDoublePointer().trap(height));
148+
// }
149+
// }
150+

leetcode/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ import "./searchWord"
2020
import "./stringCalculate"
2121
import "./MathSqrt"
2222
import "./search-binary-tree/index"
23-
import "./link-list/rotateList"
23+
import "./link-list/rotateList"
24+
import "./dynamic-programing/water-problem"

0 commit comments

Comments
 (0)