Skip to content

Commit ba49b7f

Browse files
authored
feat: add solutions to lcci problem: No.17.21 (#1340)
No.17.21.Volume of Histogram
1 parent d54f49e commit ba49b7f

File tree

8 files changed

+378
-94
lines changed

8 files changed

+378
-94
lines changed

lcci/17.21.Volume of Histogram/README.md

+132-28
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@
2020

2121
<!-- 这里可写通用的实现逻辑 -->
2222

23-
动态规划法。
23+
**方法一:动态规划**
2424

25-
对于下标 i,水能达到的最大高度等于下标 i 左右两侧的最大高度的最小值,再减去 `height[i]` 就能得到当前柱子所能存的水量
25+
我们定义 $left[i]$ 表示下标 $i$ 位置及其左边的最高柱子的高度,定义 $right[i]$ 表示下标 $i$ 位置及其右边的最高柱子的高度。那么下标 $i$ 位置能接的雨水量为 $min(left[i], right[i]) - height[i]$。我们遍历数组,计算出 $left[i]$ 和 $right[i]$,最后答案为 $\sum_{i=0}^{n-1} min(left[i], right[i]) - height[i]$
2626

27-
[42. 接雨水](/solution/0000-0099/0042.Trapping%20Rain%20Water/README.md)
27+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
28+
29+
相似题目:
30+
31+
- [42. 接雨水](/solution/0000-0099/0042.Trapping%20Rain%20Water/README.md)
2832

2933
<!-- tabs:start -->
3034

@@ -38,19 +42,12 @@ class Solution:
3842
n = len(height)
3943
if n < 3:
4044
return 0
41-
42-
left_max = [height[0]] * n
45+
left = [height[0]] * n
46+
right = [height[-1]] * n
4347
for i in range(1, n):
44-
left_max[i] = max(left_max[i - 1], height[i])
45-
46-
right_max = [height[n - 1]] * n
47-
for i in range(n - 2, -1, -1):
48-
right_max[i] = max(right_max[i + 1], height[i])
49-
50-
res = 0
51-
for i in range(n):
52-
res += min(left_max[i], right_max[i]) - height[i]
53-
return res
48+
left[i] = max(left[i - 1], height[i])
49+
right[n - i - 1] = max(right[n - i], height[n - i - 1])
50+
return sum(min(l, r) - h for l, r, h in zip(left, right, height))
5451
```
5552

5653
### **Java**
@@ -60,26 +57,133 @@ class Solution:
6057
```java
6158
class Solution {
6259
public int trap(int[] height) {
63-
int n;
64-
if ((n = height.length) < 3) return 0;
65-
66-
int[] leftMax = new int[n];
67-
leftMax[0] = height[0];
60+
int n = height.length;
61+
if (n < 3) {
62+
return 0;
63+
}
64+
int[] left = new int[n];
65+
int[] right = new int[n];
66+
left[0] = height[0];
67+
right[n - 1] = height[n - 1];
6868
for (int i = 1; i < n; ++i) {
69-
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
69+
left[i] = Math.max(left[i - 1], height[i]);
70+
right[n - i - 1] = Math.max(right[n - i], height[n - i - 1]);
7071
}
72+
int ans = 0;
73+
for (int i = 0; i < n; ++i) {
74+
ans += Math.min(left[i], right[i]) - height[i];
75+
}
76+
return ans;
77+
}
78+
}
79+
```
80+
81+
### **C++**
7182

72-
int[] rightMax = new int[n];
73-
rightMax[n - 1] = height[n - 1];
74-
for (int i = n - 2; i >= 0; --i) {
75-
rightMax[i] = Math.max(rightMax[i + 1], height[i]);
83+
```cpp
84+
class Solution {
85+
public:
86+
int trap(vector<int>& height) {
87+
int n = height.size();
88+
if (n < 3) {
89+
return 0;
7690
}
91+
int left[n], right[n];
92+
left[0] = height[0];
93+
right[n - 1] = height[n - 1];
94+
for (int i = 1; i < n; ++i) {
95+
left[i] = max(left[i - 1], height[i]);
96+
right[n - i - 1] = max(right[n - i], height[n - i - 1]);
97+
}
98+
int ans = 0;
99+
for (int i = 0; i < n; ++i) {
100+
ans += min(left[i], right[i]) - height[i];
101+
}
102+
return ans;
103+
}
104+
};
105+
```
106+
107+
### **Go**
108+
109+
```go
110+
func trap(height []int) (ans int) {
111+
n := len(height)
112+
if n < 3 {
113+
return 0
114+
}
115+
left := make([]int, n)
116+
right := make([]int, n)
117+
left[0], right[n-1] = height[0], height[n-1]
118+
for i := 1; i < n; i++ {
119+
left[i] = max(left[i-1], height[i])
120+
right[n-i-1] = max(right[n-i], height[n-i-1])
121+
}
122+
for i, h := range height {
123+
ans += min(left[i], right[i]) - h
124+
}
125+
return
126+
}
127+
128+
func max(a, b int) int {
129+
if a > b {
130+
return a
131+
}
132+
return b
133+
}
77134
78-
int res = 0;
135+
func min(a, b int) int {
136+
if a < b {
137+
return a
138+
}
139+
return b
140+
}
141+
```
142+
143+
### **TypeScript**
144+
145+
```ts
146+
function trap(height: number[]): number {
147+
const n = height.length;
148+
if (n < 3) {
149+
return 0;
150+
}
151+
const left: number[] = new Array(n).fill(height[0]);
152+
const right: number[] = new Array(n).fill(height[n - 1]);
153+
for (let i = 1; i < n; ++i) {
154+
left[i] = Math.max(left[i - 1], height[i]);
155+
right[n - i - 1] = Math.max(right[n - i], height[n - i - 1]);
156+
}
157+
let ans = 0;
158+
for (let i = 0; i < n; ++i) {
159+
ans += Math.min(left[i], right[i]) - height[i];
160+
}
161+
return ans;
162+
}
163+
```
164+
165+
### **C#**
166+
167+
```cs
168+
public class Solution {
169+
public int Trap(int[] height) {
170+
int n = height.Length;
171+
if (n < 3) {
172+
return 0;
173+
}
174+
int[] left = new int[n];
175+
int[] right = new int[n];
176+
left[0] = height[0];
177+
right[n - 1] = height[n - 1];
178+
for (int i = 1; i < n; ++i) {
179+
left[i] = Math.Max(left[i - 1], height[i]);
180+
right[n - i - 1] = Math.Max(right[n - i], height[n - i - 1]);
181+
}
182+
int ans = 0;
79183
for (int i = 0; i < n; ++i) {
80-
res += Math.min(leftMax[i], rightMax[i]) - height[i];
184+
ans += Math.Min(left[i], right[i]) - height[i];
81185
}
82-
return res;
186+
return ans;
83187
}
84188
}
85189
```

lcci/17.21.Volume of Histogram/README_EN.md

+125-25
Original file line numberDiff line numberDiff line change
@@ -30,46 +30,146 @@ class Solution:
3030
n = len(height)
3131
if n < 3:
3232
return 0
33-
34-
left_max = [height[0]] * n
33+
left = [height[0]] * n
34+
right = [height[-1]] * n
3535
for i in range(1, n):
36-
left_max[i] = max(left_max[i - 1], height[i])
37-
38-
right_max = [height[n - 1]] * n
39-
for i in range(n - 2, -1, -1):
40-
right_max[i] = max(right_max[i + 1], height[i])
41-
42-
res = 0
43-
for i in range(n):
44-
res += min(left_max[i], right_max[i]) - height[i]
45-
return res
36+
left[i] = max(left[i - 1], height[i])
37+
right[n - i - 1] = max(right[n - i], height[n - i - 1])
38+
return sum(min(l, r) - h for l, r, h in zip(left, right, height))
4639
```
4740

4841
### **Java**
4942

5043
```java
5144
class Solution {
5245
public int trap(int[] height) {
53-
int n;
54-
if ((n = height.length) < 3) return 0;
55-
56-
int[] leftMax = new int[n];
57-
leftMax[0] = height[0];
46+
int n = height.length;
47+
if (n < 3) {
48+
return 0;
49+
}
50+
int[] left = new int[n];
51+
int[] right = new int[n];
52+
left[0] = height[0];
53+
right[n - 1] = height[n - 1];
5854
for (int i = 1; i < n; ++i) {
59-
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
55+
left[i] = Math.max(left[i - 1], height[i]);
56+
right[n - i - 1] = Math.max(right[n - i], height[n - i - 1]);
6057
}
58+
int ans = 0;
59+
for (int i = 0; i < n; ++i) {
60+
ans += Math.min(left[i], right[i]) - height[i];
61+
}
62+
return ans;
63+
}
64+
}
65+
```
66+
67+
### **C++**
6168

62-
int[] rightMax = new int[n];
63-
rightMax[n - 1] = height[n - 1];
64-
for (int i = n - 2; i >= 0; --i) {
65-
rightMax[i] = Math.max(rightMax[i + 1], height[i]);
69+
```cpp
70+
class Solution {
71+
public:
72+
int trap(vector<int>& height) {
73+
int n = height.size();
74+
if (n < 3) {
75+
return 0;
76+
}
77+
int left[n], right[n];
78+
left[0] = height[0];
79+
right[n - 1] = height[n - 1];
80+
for (int i = 1; i < n; ++i) {
81+
left[i] = max(left[i - 1], height[i]);
82+
right[n - i - 1] = max(right[n - i], height[n - i - 1]);
6683
}
84+
int ans = 0;
85+
for (int i = 0; i < n; ++i) {
86+
ans += min(left[i], right[i]) - height[i];
87+
}
88+
return ans;
89+
}
90+
};
91+
```
6792
68-
int res = 0;
93+
### **Go**
94+
95+
```go
96+
func trap(height []int) (ans int) {
97+
n := len(height)
98+
if n < 3 {
99+
return 0
100+
}
101+
left := make([]int, n)
102+
right := make([]int, n)
103+
left[0], right[n-1] = height[0], height[n-1]
104+
for i := 1; i < n; i++ {
105+
left[i] = max(left[i-1], height[i])
106+
right[n-i-1] = max(right[n-i], height[n-i-1])
107+
}
108+
for i, h := range height {
109+
ans += min(left[i], right[i]) - h
110+
}
111+
return
112+
}
113+
114+
func max(a, b int) int {
115+
if a > b {
116+
return a
117+
}
118+
return b
119+
}
120+
121+
func min(a, b int) int {
122+
if a < b {
123+
return a
124+
}
125+
return b
126+
}
127+
```
128+
129+
### **TypeScript**
130+
131+
```ts
132+
function trap(height: number[]): number {
133+
const n = height.length;
134+
if (n < 3) {
135+
return 0;
136+
}
137+
const left: number[] = new Array(n).fill(height[0]);
138+
const right: number[] = new Array(n).fill(height[n - 1]);
139+
for (let i = 1; i < n; ++i) {
140+
left[i] = Math.max(left[i - 1], height[i]);
141+
right[n - i - 1] = Math.max(right[n - i], height[n - i - 1]);
142+
}
143+
let ans = 0;
144+
for (let i = 0; i < n; ++i) {
145+
ans += Math.min(left[i], right[i]) - height[i];
146+
}
147+
return ans;
148+
}
149+
```
150+
151+
### **C#**
152+
153+
```cs
154+
public class Solution {
155+
public int Trap(int[] height) {
156+
int n = height.Length;
157+
if (n < 3) {
158+
return 0;
159+
}
160+
int[] left = new int[n];
161+
int[] right = new int[n];
162+
left[0] = height[0];
163+
right[n - 1] = height[n - 1];
164+
for (int i = 1; i < n; ++i) {
165+
left[i] = Math.Max(left[i - 1], height[i]);
166+
right[n - i - 1] = Math.Max(right[n - i], height[n - i - 1]);
167+
}
168+
int ans = 0;
69169
for (int i = 0; i < n; ++i) {
70-
res += Math.min(leftMax[i], rightMax[i]) - height[i];
170+
ans += Math.Min(left[i], right[i]) - height[i];
71171
}
72-
return res;
172+
return ans;
73173
}
74174
}
75175
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public:
3+
int trap(vector<int>& height) {
4+
int n = height.size();
5+
if (n < 3) {
6+
return 0;
7+
}
8+
int left[n], right[n];
9+
left[0] = height[0];
10+
right[n - 1] = height[n - 1];
11+
for (int i = 1; i < n; ++i) {
12+
left[i] = max(left[i - 1], height[i]);
13+
right[n - i - 1] = max(right[n - i], height[n - i - 1]);
14+
}
15+
int ans = 0;
16+
for (int i = 0; i < n; ++i) {
17+
ans += min(left[i], right[i]) - height[i];
18+
}
19+
return ans;
20+
}
21+
};

0 commit comments

Comments
 (0)