Skip to content

Commit 4bc5015

Browse files
committed
feat: add solutions to lc problem: No.0795
No.0795.Number of Subarrays with Bounded Maximum
1 parent f8f129d commit 4bc5015

File tree

6 files changed

+391
-2
lines changed

6 files changed

+391
-2
lines changed

solution/0700-0799/0795.Number of Subarrays with Bounded Maximum/README.md

+140-1
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,161 @@
4141

4242
<!-- 这里可写通用的实现逻辑 -->
4343

44+
**方法一:单调栈**
45+
46+
我们可以枚举数组中每个元素作为子数组的最大值,然后统计以该元素为最大值的子数组的个数。问题转化为求出每个元素 $nums[i]$ 左侧第一个大于该元素的下标 $l[i]$,右侧第一个大于等于该元素的下标 $r[i]$,则以该元素为最大值的子数组的个数为 $(i - left[i]) \times (right[i] - i)$。
47+
48+
我们可以使用单调栈求出 $l[i]$ 和 $r[i]$。
49+
50+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。
51+
52+
相似题目:[907. 子数组的最小值之和](/solution/0900-0999/0907.Sum%20of%20Subarray%20Minimums/README.md)
53+
4454
<!-- tabs:start -->
4555

4656
### **Python3**
4757

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

5060
```python
51-
61+
class Solution:
62+
def numSubarrayBoundedMax(self, nums: List[int], left: int, right: int) -> int:
63+
n = len(nums)
64+
l, r = [-1] * n, [n] * n
65+
stk = []
66+
for i, v in enumerate(nums):
67+
while stk and nums[stk[-1]] <= v:
68+
stk.pop()
69+
if stk:
70+
l[i] = stk[-1]
71+
stk.append(i)
72+
stk = []
73+
for i in range(n - 1, -1, -1):
74+
while stk and nums[stk[-1]] < nums[i]:
75+
stk.pop()
76+
if stk:
77+
r[i] = stk[-1]
78+
stk.append(i)
79+
return sum((i - l[i]) * (r[i] - i) for i, v in enumerate(nums) if left <= v <= right)
5280
```
5381

5482
### **Java**
5583

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

5886
```java
87+
class Solution {
88+
public int numSubarrayBoundedMax(int[] nums, int left, int right) {
89+
int n = nums.length;
90+
int[] l = new int[n];
91+
int[] r = new int[n];
92+
Arrays.fill(l, -1);
93+
Arrays.fill(r, n);
94+
Deque<Integer> stk = new ArrayDeque<>();
95+
for (int i = 0; i < n; ++i) {
96+
int v = nums[i];
97+
while (!stk.isEmpty() && nums[stk.peek()] <= v) {
98+
stk.pop();
99+
}
100+
if (!stk.isEmpty()) {
101+
l[i] = stk.peek();
102+
}
103+
stk.push(i);
104+
}
105+
stk.clear();
106+
for (int i = n - 1; i >= 0; --i) {
107+
int v = nums[i];
108+
while (!stk.isEmpty() && nums[stk.peek()] < v) {
109+
stk.pop();
110+
}
111+
if (!stk.isEmpty()) {
112+
r[i] = stk.peek();
113+
}
114+
stk.push(i);
115+
}
116+
int ans = 0;
117+
for (int i = 0; i < n; ++i) {
118+
if (left <= nums[i] && nums[i] <= right) {
119+
ans += (i - l[i]) * (r[i] - i);
120+
}
121+
}
122+
return ans;
123+
}
124+
}
125+
```
126+
127+
### **C++**
128+
129+
```cpp
130+
class Solution {
131+
public:
132+
int numSubarrayBoundedMax(vector<int>& nums, int left, int right) {
133+
int n = nums.size();
134+
vector<int> l(n, -1);
135+
vector<int> r(n, n);
136+
stack<int> stk;
137+
for (int i = 0; i < n; ++i) {
138+
int v = nums[i];
139+
while (!stk.empty() && nums[stk.top()] <= v) stk.pop();
140+
if (!stk.empty()) l[i] = stk.top();
141+
stk.push(i);
142+
}
143+
stk = stack<int>();
144+
for (int i = n - 1; ~i; --i) {
145+
int v = nums[i];
146+
while (!stk.empty() && nums[stk.top()] < v) stk.pop();
147+
if (!stk.empty()) r[i] = stk.top();
148+
stk.push(i);
149+
}
150+
int ans = 0;
151+
for (int i = 0; i < n; ++i) {
152+
if (left <= nums[i] && nums[i] <= right) {
153+
ans += (i - l[i]) * (r[i] - i);
154+
}
155+
}
156+
return ans;
157+
}
158+
};
159+
```
59160
161+
### **Go**
162+
163+
```go
164+
func numSubarrayBoundedMax(nums []int, left int, right int) (ans int) {
165+
n := len(nums)
166+
l := make([]int, n)
167+
r := make([]int, n)
168+
for i := range l {
169+
l[i], r[i] = -1, n
170+
}
171+
stk := []int{}
172+
for i, v := range nums {
173+
for len(stk) > 0 && nums[stk[len(stk)-1]] <= v {
174+
stk = stk[:len(stk)-1]
175+
}
176+
if len(stk) > 0 {
177+
l[i] = stk[len(stk)-1]
178+
}
179+
stk = append(stk, i)
180+
}
181+
stk = []int{}
182+
for i := n - 1; i >= 0; i-- {
183+
v := nums[i]
184+
for len(stk) > 0 && nums[stk[len(stk)-1]] < v {
185+
stk = stk[:len(stk)-1]
186+
}
187+
if len(stk) > 0 {
188+
r[i] = stk[len(stk)-1]
189+
}
190+
stk = append(stk, i)
191+
}
192+
for i, v := range nums {
193+
if left <= v && v <= right {
194+
ans += (i - l[i]) * (r[i] - i)
195+
}
196+
}
197+
return
198+
}
60199
```
61200

62201
### **...**

solution/0700-0799/0795.Number of Subarrays with Bounded Maximum/README_EN.md

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

4242
```python
43-
43+
class Solution:
44+
def numSubarrayBoundedMax(self, nums: List[int], left: int, right: int) -> int:
45+
n = len(nums)
46+
l, r = [-1] * n, [n] * n
47+
stk = []
48+
for i, v in enumerate(nums):
49+
while stk and nums[stk[-1]] <= v:
50+
stk.pop()
51+
if stk:
52+
l[i] = stk[-1]
53+
stk.append(i)
54+
stk = []
55+
for i in range(n - 1, -1, -1):
56+
while stk and nums[stk[-1]] < nums[i]:
57+
stk.pop()
58+
if stk:
59+
r[i] = stk[-1]
60+
stk.append(i)
61+
return sum((i - l[i]) * (r[i] - i) for i, v in enumerate(nums) if left <= v <= right)
4462
```
4563

4664
### **Java**
4765

4866
```java
67+
class Solution {
68+
public int numSubarrayBoundedMax(int[] nums, int left, int right) {
69+
int n = nums.length;
70+
int[] l = new int[n];
71+
int[] r = new int[n];
72+
Arrays.fill(l, -1);
73+
Arrays.fill(r, n);
74+
Deque<Integer> stk = new ArrayDeque<>();
75+
for (int i = 0; i < n; ++i) {
76+
int v = nums[i];
77+
while (!stk.isEmpty() && nums[stk.peek()] <= v) {
78+
stk.pop();
79+
}
80+
if (!stk.isEmpty()) {
81+
l[i] = stk.peek();
82+
}
83+
stk.push(i);
84+
}
85+
stk.clear();
86+
for (int i = n - 1; i >= 0; --i) {
87+
int v = nums[i];
88+
while (!stk.isEmpty() && nums[stk.peek()] < v) {
89+
stk.pop();
90+
}
91+
if (!stk.isEmpty()) {
92+
r[i] = stk.peek();
93+
}
94+
stk.push(i);
95+
}
96+
int ans = 0;
97+
for (int i = 0; i < n; ++i) {
98+
if (left <= nums[i] && nums[i] <= right) {
99+
ans += (i - l[i]) * (r[i] - i);
100+
}
101+
}
102+
return ans;
103+
}
104+
}
105+
```
106+
107+
### **C++**
108+
109+
```cpp
110+
class Solution {
111+
public:
112+
int numSubarrayBoundedMax(vector<int>& nums, int left, int right) {
113+
int n = nums.size();
114+
vector<int> l(n, -1);
115+
vector<int> r(n, n);
116+
stack<int> stk;
117+
for (int i = 0; i < n; ++i) {
118+
int v = nums[i];
119+
while (!stk.empty() && nums[stk.top()] <= v) stk.pop();
120+
if (!stk.empty()) l[i] = stk.top();
121+
stk.push(i);
122+
}
123+
stk = stack<int>();
124+
for (int i = n - 1; ~i; --i) {
125+
int v = nums[i];
126+
while (!stk.empty() && nums[stk.top()] < v) stk.pop();
127+
if (!stk.empty()) r[i] = stk.top();
128+
stk.push(i);
129+
}
130+
int ans = 0;
131+
for (int i = 0; i < n; ++i) {
132+
if (left <= nums[i] && nums[i] <= right) {
133+
ans += (i - l[i]) * (r[i] - i);
134+
}
135+
}
136+
return ans;
137+
}
138+
};
139+
```
49140
141+
### **Go**
142+
143+
```go
144+
func numSubarrayBoundedMax(nums []int, left int, right int) (ans int) {
145+
n := len(nums)
146+
l := make([]int, n)
147+
r := make([]int, n)
148+
for i := range l {
149+
l[i], r[i] = -1, n
150+
}
151+
stk := []int{}
152+
for i, v := range nums {
153+
for len(stk) > 0 && nums[stk[len(stk)-1]] <= v {
154+
stk = stk[:len(stk)-1]
155+
}
156+
if len(stk) > 0 {
157+
l[i] = stk[len(stk)-1]
158+
}
159+
stk = append(stk, i)
160+
}
161+
stk = []int{}
162+
for i := n - 1; i >= 0; i-- {
163+
v := nums[i]
164+
for len(stk) > 0 && nums[stk[len(stk)-1]] < v {
165+
stk = stk[:len(stk)-1]
166+
}
167+
if len(stk) > 0 {
168+
r[i] = stk[len(stk)-1]
169+
}
170+
stk = append(stk, i)
171+
}
172+
for i, v := range nums {
173+
if left <= v && v <= right {
174+
ans += (i - l[i]) * (r[i] - i)
175+
}
176+
}
177+
return
178+
}
50179
```
51180

52181
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution {
2+
public:
3+
int numSubarrayBoundedMax(vector<int>& nums, int left, int right) {
4+
int n = nums.size();
5+
vector<int> l(n, -1);
6+
vector<int> r(n, n);
7+
stack<int> stk;
8+
for (int i = 0; i < n; ++i) {
9+
int v = nums[i];
10+
while (!stk.empty() && nums[stk.top()] <= v) stk.pop();
11+
if (!stk.empty()) l[i] = stk.top();
12+
stk.push(i);
13+
}
14+
stk = stack<int>();
15+
for (int i = n - 1; ~i; --i) {
16+
int v = nums[i];
17+
while (!stk.empty() && nums[stk.top()] < v) stk.pop();
18+
if (!stk.empty()) r[i] = stk.top();
19+
stk.push(i);
20+
}
21+
int ans = 0;
22+
for (int i = 0; i < n; ++i) {
23+
if (left <= nums[i] && nums[i] <= right) {
24+
ans += (i - l[i]) * (r[i] - i);
25+
}
26+
}
27+
return ans;
28+
}
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
func numSubarrayBoundedMax(nums []int, left int, right int) (ans int) {
2+
n := len(nums)
3+
l := make([]int, n)
4+
r := make([]int, n)
5+
for i := range l {
6+
l[i], r[i] = -1, n
7+
}
8+
stk := []int{}
9+
for i, v := range nums {
10+
for len(stk) > 0 && nums[stk[len(stk)-1]] <= v {
11+
stk = stk[:len(stk)-1]
12+
}
13+
if len(stk) > 0 {
14+
l[i] = stk[len(stk)-1]
15+
}
16+
stk = append(stk, i)
17+
}
18+
stk = []int{}
19+
for i := n - 1; i >= 0; i-- {
20+
v := nums[i]
21+
for len(stk) > 0 && nums[stk[len(stk)-1]] < v {
22+
stk = stk[:len(stk)-1]
23+
}
24+
if len(stk) > 0 {
25+
r[i] = stk[len(stk)-1]
26+
}
27+
stk = append(stk, i)
28+
}
29+
for i, v := range nums {
30+
if left <= v && v <= right {
31+
ans += (i - l[i]) * (r[i] - i)
32+
}
33+
}
34+
return
35+
}

0 commit comments

Comments
 (0)