Skip to content

Commit 6cefe38

Browse files
committed
feat: add solutions to lc problem: No.0962
No.0962.Maximum Width Ramp
1 parent bdf018b commit 6cefe38

File tree

11 files changed

+286
-7
lines changed

11 files changed

+286
-7
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
- [下一个更大元素 I](/solution/0400-0499/0496.Next%20Greater%20Element%20I/README.md) - `单调栈`
5959
- [每日温度](/solution/0700-0799/0739.Daily%20Temperatures/README.md) - `单调栈`
6060
- [子数组的最小值之和](/solution/0900-0999/0907.Sum%20of%20Subarray%20Minimums/README.md) - `单调栈`
61+
- [最大宽度坡](/solution/0900-0999/0962.Maximum%20Width%20Ramp/README.md) - `单调栈`
6162
- [子数组范围和](/solution/2100-2199/2104.Sum%20of%20Subarray%20Ranges/README.md) - `单调栈`
6263
- [子数组最小乘积的最大值](/solution/1800-1899/1856.Maximum%20Subarray%20Min-Product/README.md) - `单调栈`
6364
- [滑动窗口最大值](/solution/0200-0299/0239.Sliding%20Window%20Maximum/README.md) - `单调队列`

README_EN.md

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Complete solutions to [LeetCode](https://leetcode.com/problemset/all/), [LCOF](h
5656
- [Next Greater Element I](/solution/0400-0499/0496.Next%20Greater%20Element%20I/README_EN.md) - `Monotonic Stack`
5757
- [Daily Temperatures](/solution/0700-0799/0739.Daily%20Temperatures/README_EN.md) - `Monotonic Stack`
5858
- [Sum of Subarray Minimums](/solution/0900-0999/0907.Sum%20of%20Subarray%20Minimums/README_EN.md) - `Monotonic Stack`
59+
- [Maximum Width Ramp](/solution/0900-0999/0962.Maximum%20Width%20Ramp/README_EN.md) - `Monotonic Stack`
5960
- [Sum of Subarray Ranges](/solution/2100-2199/2104.Sum%20of%20Subarray%20Ranges/README_EN.md) - `Monotonic Stack`
6061
- [Maximum Subarray Min-Product](/solution/1800-1899/1856.Maximum%20Subarray%20Min-Product/README_EN.md) - `Monotonic Stack`
6162
- [Sliding Window Maximum](/solution/0200-0299/0239.Sliding%20Window%20Maximum/README_EN.md) - `Monotonic Queue`

solution/0900-0999/0907.Sum of Subarray Minimums/README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,14 @@
4545

4646
**方法一:单调栈**
4747

48-
枚举 `arr[i]` 作为子数组的最小值,找出左侧第一个比 `arr[i]` 小的位置 `left[i]`,右侧第一个不大于 `arr[i]` 的位置 `right[i]`
48+
枚举 $arr[i]$ 作为子数组的最小值,找出左侧第一个比 $arr[i]$ 小的位置 $left[i]$,右侧第一个不大于 $arr[i]$ 的位置 $right[i]$。由此可以算出最小值 $arr[i]$ 可以出现在多少个子数组中
4949

50-
计算每个 `arr[i]` 的贡献 `(i - left[i]) * (right[i] - i) * arr[i]`,累加得到结果。
50+
计算每个 $arr[i]$ 的贡献 $(i-left[i])*(right[i]-i)*arr[i]$,累加得到结果。
5151

5252
注意数据溢出与取模操作。
5353

54+
时间复杂度 $O(n)$,其中 $n$ 表示数组 $arr$ 的长度。
55+
5456
<!-- tabs:start -->
5557

5658
### **Python3**
@@ -64,7 +66,6 @@ class Solution:
6466
left = [-1] * n
6567
right = [n] * n
6668
stk = []
67-
mod = int(1e9) + 7
6869
for i, v in enumerate(arr):
6970
while stk and arr[stk[-1]] >= v:
7071
stk.pop()
@@ -78,6 +79,7 @@ class Solution:
7879
if stk:
7980
right[i] = stk[-1]
8081
stk.append(i)
82+
mod = int(1e9) + 7
8183
return sum((i - left[i]) * (right[i] - i) * v for i, v in enumerate(arr)) % mod
8284
```
8385

solution/0900-0999/0907.Sum of Subarray Minimums/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ class Solution:
4646
left = [-1] * n
4747
right = [n] * n
4848
stk = []
49-
mod = int(1e9) + 7
5049
for i, v in enumerate(arr):
5150
while stk and arr[stk[-1]] >= v:
5251
stk.pop()
@@ -60,6 +59,7 @@ class Solution:
6059
if stk:
6160
right[i] = stk[-1]
6261
stk.append(i)
62+
mod = int(1e9) + 7
6363
return sum((i - left[i]) * (right[i] - i) * v for i, v in enumerate(arr)) % mod
6464
```
6565

solution/0900-0999/0907.Sum of Subarray Minimums/Solution.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ def sumSubarrayMins(self, arr: List[int]) -> int:
44
left = [-1] * n
55
right = [n] * n
66
stk = []
7-
mod = int(1e9) + 7
87
for i, v in enumerate(arr):
98
while stk and arr[stk[-1]] >= v:
109
stk.pop()
@@ -18,4 +17,5 @@ def sumSubarrayMins(self, arr: List[int]) -> int:
1817
if stk:
1918
right[i] = stk[-1]
2019
stk.append(i)
20+
mod = int(1e9) + 7
2121
return sum((i - left[i]) * (right[i] - i) * v for i, v in enumerate(arr)) % mod

solution/0900-0999/0962.Maximum Width Ramp/README.md

+102-1
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,123 @@
4343

4444
<!-- 这里可写通用的实现逻辑 -->
4545

46+
**方法一:单调栈**
47+
48+
根据题意,我们可以发现,所有可能的 $nums[i]$ 所构成的子序列一定是单调递减的。为什么呢?我们不妨用反证法证明一下。
49+
50+
假设存在 $i_1<i_2$,并且 $nums[i_1]<=nums[i_2]$,那么实际上 $nums[i_2]$一定不可能是一个候选值,因为 $nums[i_1]$ 更靠左,会是一个更优的值。因此 $nums[i]$ 所构成的子序列一定单调递减,并且 $i$ 一定是从 0 开始。
51+
52+
我们用一个从栈底到栈顶单调递减的栈 $stk$ 来存储所有可能的 $nums[i]$,然后我们从右边界开始遍历 $j$,若遇到 $nums[stk.top()]<=nums[j]$,说明此时构成一个坡,循环弹出栈顶元素,更新 ans。
53+
54+
时间复杂度 $O(n)$,其中 $n$ 表示 $nums$ 的长度。
55+
4656
<!-- tabs:start -->
4757

4858
### **Python3**
4959

5060
<!-- 这里可写当前语言的特殊实现逻辑 -->
5161

5262
```python
53-
63+
class Solution:
64+
def maxWidthRamp(self, nums: List[int]) -> int:
65+
stk = []
66+
for i, v in enumerate(nums):
67+
if not stk or nums[stk[-1]] > v:
68+
stk.append(i)
69+
ans = 0
70+
for i in range(len(nums) - 1, -1, -1):
71+
while stk and nums[stk[-1]] <= nums[i]:
72+
ans = max(ans, i - stk.pop())
73+
if not stk:
74+
break
75+
return ans
5476
```
5577

5678
### **Java**
5779

5880
<!-- 这里可写当前语言的特殊实现逻辑 -->
5981

6082
```java
83+
class Solution {
84+
public int maxWidthRamp(int[] nums) {
85+
int n = nums.length;
86+
Deque<Integer> stk = new ArrayDeque<>();
87+
for (int i = 0; i < n; ++i) {
88+
if (stk.isEmpty() || nums[stk.peek()] > nums[i]) {
89+
stk.push(i);
90+
}
91+
}
92+
int ans = 0;
93+
for (int i = n - 1; i >= 0; --i) {
94+
while (!stk.isEmpty() && nums[stk.peek()] <= nums[i]) {
95+
ans = Math.max(ans, i - stk.pop());
96+
}
97+
if (stk.isEmpty()) {
98+
break;
99+
}
100+
}
101+
return ans;
102+
}
103+
}
104+
```
105+
106+
### **C++**
107+
108+
```cpp
109+
class Solution {
110+
public:
111+
int maxWidthRamp(vector<int>& nums) {
112+
int n = nums.size();
113+
stack<int> stk;
114+
for (int i = 0; i < n; ++i)
115+
{
116+
if (stk.empty() || nums[stk.top()] > nums[i]) stk.push(i);
117+
}
118+
int ans = 0;
119+
for (int i = n - 1; i; --i)
120+
{
121+
while (!stk.empty() && nums[stk.top()] <= nums[i])
122+
{
123+
ans = max(ans, i - stk.top());
124+
stk.pop();
125+
}
126+
if (stk.empty()) break;
127+
}
128+
return ans;
129+
}
130+
};
131+
```
61132
133+
### **Go**
134+
135+
```go
136+
func maxWidthRamp(nums []int) int {
137+
n := len(nums)
138+
stk := []int{}
139+
for i, v := range nums {
140+
if len(stk) == 0 || nums[stk[len(stk)-1]] > v {
141+
stk = append(stk, i)
142+
}
143+
}
144+
ans := 0
145+
for i := n - 1; i >= 0; i-- {
146+
for len(stk) > 0 && nums[stk[len(stk)-1]] <= nums[i] {
147+
ans = max(ans, i-stk[len(stk)-1])
148+
stk = stk[:len(stk)-1]
149+
}
150+
if len(stk) == 0 {
151+
break
152+
}
153+
}
154+
return ans
155+
}
156+
157+
func max(a, b int) int {
158+
if a > b {
159+
return a
160+
}
161+
return b
162+
}
62163
```
63164

64165
### **...**

solution/0900-0999/0962.Maximum Width Ramp/README_EN.md

+92-1
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,104 @@
4040
### **Python3**
4141

4242
```python
43-
43+
class Solution:
44+
def maxWidthRamp(self, nums: List[int]) -> int:
45+
stk = []
46+
for i, v in enumerate(nums):
47+
if not stk or nums[stk[-1]] > v:
48+
stk.append(i)
49+
ans = 0
50+
for i in range(len(nums) - 1, -1, -1):
51+
while stk and nums[stk[-1]] <= nums[i]:
52+
ans = max(ans, i - stk.pop())
53+
if not stk:
54+
break
55+
return ans
4456
```
4557

4658
### **Java**
4759

4860
```java
61+
class Solution {
62+
public int maxWidthRamp(int[] nums) {
63+
int n = nums.length;
64+
Deque<Integer> stk = new ArrayDeque<>();
65+
for (int i = 0; i < n; ++i) {
66+
if (stk.isEmpty() || nums[stk.peek()] > nums[i]) {
67+
stk.push(i);
68+
}
69+
}
70+
int ans = 0;
71+
for (int i = n - 1; i >= 0; --i) {
72+
while (!stk.isEmpty() && nums[stk.peek()] <= nums[i]) {
73+
ans = Math.max(ans, i - stk.pop());
74+
}
75+
if (stk.isEmpty()) {
76+
break;
77+
}
78+
}
79+
return ans;
80+
}
81+
}
82+
```
83+
84+
### **C++**
85+
86+
```cpp
87+
class Solution {
88+
public:
89+
int maxWidthRamp(vector<int>& nums) {
90+
int n = nums.size();
91+
stack<int> stk;
92+
for (int i = 0; i < n; ++i)
93+
{
94+
if (stk.empty() || nums[stk.top()] > nums[i]) stk.push(i);
95+
}
96+
int ans = 0;
97+
for (int i = n - 1; i; --i)
98+
{
99+
while (!stk.empty() && nums[stk.top()] <= nums[i])
100+
{
101+
ans = max(ans, i - stk.top());
102+
stk.pop();
103+
}
104+
if (stk.empty()) break;
105+
}
106+
return ans;
107+
}
108+
};
109+
```
49110
111+
### **Go**
112+
113+
```go
114+
func maxWidthRamp(nums []int) int {
115+
n := len(nums)
116+
stk := []int{}
117+
for i, v := range nums {
118+
if len(stk) == 0 || nums[stk[len(stk)-1]] > v {
119+
stk = append(stk, i)
120+
}
121+
}
122+
ans := 0
123+
for i := n - 1; i >= 0; i-- {
124+
for len(stk) > 0 && nums[stk[len(stk)-1]] <= nums[i] {
125+
ans = max(ans, i-stk[len(stk)-1])
126+
stk = stk[:len(stk)-1]
127+
}
128+
if len(stk) == 0 {
129+
break
130+
}
131+
}
132+
return ans
133+
}
134+
135+
func max(a, b int) int {
136+
if a > b {
137+
return a
138+
}
139+
return b
140+
}
50141
```
51142

52143
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution {
2+
public:
3+
int maxWidthRamp(vector<int>& nums) {
4+
int n = nums.size();
5+
stack<int> stk;
6+
for (int i = 0; i < n; ++i)
7+
{
8+
if (stk.empty() || nums[stk.top()] > nums[i]) stk.push(i);
9+
}
10+
int ans = 0;
11+
for (int i = n - 1; i; --i)
12+
{
13+
while (!stk.empty() && nums[stk.top()] <= nums[i])
14+
{
15+
ans = max(ans, i - stk.top());
16+
stk.pop();
17+
}
18+
if (stk.empty()) break;
19+
}
20+
return ans;
21+
}
22+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
func maxWidthRamp(nums []int) int {
2+
n := len(nums)
3+
stk := []int{}
4+
for i, v := range nums {
5+
if len(stk) == 0 || nums[stk[len(stk)-1]] > v {
6+
stk = append(stk, i)
7+
}
8+
}
9+
ans := 0
10+
for i := n - 1; i >= 0; i-- {
11+
for len(stk) > 0 && nums[stk[len(stk)-1]] <= nums[i] {
12+
ans = max(ans, i-stk[len(stk)-1])
13+
stk = stk[:len(stk)-1]
14+
}
15+
if len(stk) == 0 {
16+
break
17+
}
18+
}
19+
return ans
20+
}
21+
22+
func max(a, b int) int {
23+
if a > b {
24+
return a
25+
}
26+
return b
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public int maxWidthRamp(int[] nums) {
3+
int n = nums.length;
4+
Deque<Integer> stk = new ArrayDeque<>();
5+
for (int i = 0; i < n; ++i) {
6+
if (stk.isEmpty() || nums[stk.peek()] > nums[i]) {
7+
stk.push(i);
8+
}
9+
}
10+
int ans = 0;
11+
for (int i = n - 1; i >= 0; --i) {
12+
while (!stk.isEmpty() && nums[stk.peek()] <= nums[i]) {
13+
ans = Math.max(ans, i - stk.pop());
14+
}
15+
if (stk.isEmpty()) {
16+
break;
17+
}
18+
}
19+
return ans;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Solution:
2+
def maxWidthRamp(self, nums: List[int]) -> int:
3+
stk = []
4+
for i, v in enumerate(nums):
5+
if not stk or nums[stk[-1]] > v:
6+
stk.append(i)
7+
ans = 0
8+
for i in range(len(nums) - 1, -1, -1):
9+
while stk and nums[stk[-1]] <= nums[i]:
10+
ans = max(ans, i - stk.pop())
11+
if not stk:
12+
break
13+
return ans

0 commit comments

Comments
 (0)