Skip to content

Commit 0624f99

Browse files
committed
feat: add solutions to lc problem: No.2334
No.2334.Subarray With Elements Greater Than Varying Threshold
1 parent 51aa9c5 commit 0624f99

File tree

6 files changed

+787
-0
lines changed

6 files changed

+787
-0
lines changed

solution/2300-2399/2334.Subarray With Elements Greater Than Varying Threshold/README.md

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,362 @@
4646

4747
<!-- 这里可写通用的实现逻辑 -->
4848

49+
**方法一:并查集**
50+
51+
考虑**从大到小遍历**数组 $nums$ 中的每个元素 $v$,用并查集来维护以 $v$ 作为子数组最小值的连通块。
52+
53+
遍历过程中:
54+
55+
$v$ 在数组 $nums$ 中的下标为 $i$,若下标 $i-1$ 对应的元素遍历过,可以将 $i-1$ 与 $i$ 进行合并,同理,若下标 $i+1$ 对应的元素也遍历过了,将 $i$ 与 $i+1$ 合并。合并过程中更新连通块的大小。
56+
57+
$v$ 作为当前连通块的最小值,当前连通块的大小为 $size[find(i)]$,若 $v>\frac{\text{threshold}}{size[find(i)]}$,说明找到了满足条件的子数组,返回 $true$。
58+
59+
否则遍历结束,返回 $-1$。
60+
61+
时间复杂度 $O(nlogn)$。
62+
63+
**方法二:单调栈**
64+
65+
利用单调栈,得到以当前元素 $nums[i]$ 作为最小元素的左右边界 $left[i]$(左边第一个比 $nums[i]$ 小的元素的位置), $right[i]$(右边第一个比 $nums[i]$ 小的元素的位置)。
66+
67+
那么对于当前元素 $nums[i]$,$k=right[i]-left[i]-1$,若 $nums[i]>\frac{\text{threshold}}{k}$,说明找到了满足条件的子数组,返回 $true$。
68+
69+
否则遍历结束,返回 $-1$。
70+
71+
时间复杂度 $O(n)$。
72+
4973
<!-- tabs:start -->
5074

5175
### **Python3**
5276

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

5579
```python
80+
class Solution:
81+
def validSubarraySize(self, nums: List[int], threshold: int) -> int:
82+
def find(x):
83+
if p[x] != x:
84+
p[x] = find(p[x])
85+
return p[x]
86+
87+
def merge(a, b):
88+
pa, pb = find(a), find(b)
89+
if pa == pb:
90+
return
91+
p[pa] = pb
92+
size[pb] += size[pa]
93+
94+
n = len(nums)
95+
p = list(range(n))
96+
size = [1] * n
97+
arr = sorted(zip(nums, range(n)), reverse=True)
98+
vis = [False] * n
99+
for v, i in arr:
100+
if i and vis[i - 1]:
101+
merge(i, i - 1)
102+
if i < n - 1 and vis[i + 1]:
103+
merge(i, i + 1)
104+
if v > threshold // size[find(i)]:
105+
return size[find(i)]
106+
vis[i] = True
107+
return -1
108+
```
56109

110+
```python
111+
class Solution:
112+
def validSubarraySize(self, nums: List[int], threshold: int) -> int:
113+
n = len(nums)
114+
left = [-1] * n
115+
right = [n] * n
116+
stk = []
117+
for i, v in enumerate(nums):
118+
while stk and nums[stk[-1]] >= v:
119+
stk.pop()
120+
if stk:
121+
left[i] = stk[-1]
122+
stk.append(i)
123+
stk = []
124+
for i in range(n - 1, -1, -1):
125+
while stk and nums[stk[-1]] >= nums[i]:
126+
stk.pop()
127+
if stk:
128+
right[i] = stk[-1]
129+
stk.append(i)
130+
for i, v in enumerate(nums):
131+
k = right[i] - left[i] - 1
132+
if v > threshold // k:
133+
return k
134+
return -1
57135
```
58136

59137
### **Java**
60138

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

63141
```java
142+
class Solution {
143+
private int[] p;
144+
private int[] size;
145+
146+
public int validSubarraySize(int[] nums, int threshold) {
147+
int n = nums.length;
148+
p = new int[n];
149+
size = new int[n];
150+
for (int i = 0; i < n; ++i) {
151+
p[i] = i;
152+
size[i] = 1;
153+
}
154+
int[][] arr = new int[n][2];
155+
for (int i = 0; i < n; ++i) {
156+
arr[i][0] = nums[i];
157+
arr[i][1] = i;
158+
}
159+
Arrays.sort(arr, (a, b) -> b[0] - a[0]);
160+
boolean[] vis = new boolean[n];
161+
for (int[] e : arr) {
162+
int v = e[0], i = e[1];
163+
if (i > 0 && vis[i - 1]) {
164+
merge(i, i - 1);
165+
}
166+
if (i < n - 1 && vis[i + 1]) {
167+
merge(i, i + 1);
168+
}
169+
if (v > threshold / size[find(i)]) {
170+
return size[find(i)];
171+
}
172+
vis[i] = true;
173+
}
174+
return -1;
175+
}
176+
177+
private int find(int x) {
178+
if (p[x] != x) {
179+
p[x] = find(p[x]);
180+
}
181+
return p[x];
182+
}
183+
184+
private void merge(int a, int b) {
185+
int pa = find(a), pb = find(b);
186+
if (pa == pb) {
187+
return;
188+
}
189+
p[pa] = pb;
190+
size[pb] += size[pa];
191+
}
192+
}
193+
```
194+
195+
```java
196+
class Solution {
197+
public int validSubarraySize(int[] nums, int threshold) {
198+
int n = nums.length;
199+
int[] left = new int[n];
200+
int[] right = new int[n];
201+
Arrays.fill(left, -1);
202+
Arrays.fill(right, n);
203+
Deque<Integer> stk = new ArrayDeque<>();
204+
for (int i = 0; i < n; ++i) {
205+
int v = nums[i];
206+
while (!stk.isEmpty() && nums[stk.peek()] >= v) {
207+
stk.pop();
208+
}
209+
if (!stk.isEmpty()) {
210+
left[i] = stk.peek();
211+
}
212+
stk.push(i);
213+
}
214+
stk.clear();
215+
for (int i = n - 1; i >= 0; --i) {
216+
int v = nums[i];
217+
while (!stk.isEmpty() && nums[stk.peek()] >= v) {
218+
stk.pop();
219+
}
220+
if (!stk.isEmpty()) {
221+
right[i] = stk.peek();
222+
}
223+
stk.push(i);
224+
}
225+
for (int i = 0; i < n; ++i) {
226+
int v = nums[i];
227+
int k = right[i] - left[i] - 1;
228+
if (v > threshold / k) {
229+
return k;
230+
}
231+
}
232+
return -1;
233+
}
234+
}
235+
```
236+
237+
### **C++**
238+
239+
```cpp
240+
using pii = pair<int, int>;
241+
242+
class Solution {
243+
public:
244+
vector<int> p;
245+
vector<int> size;
246+
247+
int validSubarraySize(vector<int>& nums, int threshold) {
248+
int n = nums.size();
249+
p.resize(n);
250+
for (int i = 0; i < n; ++i) p[i] = i;
251+
size.assign(n, 1);
252+
vector<pii> arr(n);
253+
for (int i = 0; i < n; ++i) arr[i] = {nums[i], i};
254+
sort(arr.begin(), arr.end());
255+
vector<bool> vis(n);
256+
for (int j = n - 1; ~j; --j)
257+
{
258+
int v = arr[j].first, i = arr[j].second;
259+
if (i && vis[i - 1]) merge(i, i - 1);
260+
if (j < n - 1 && vis[i + 1]) merge(i, i + 1);
261+
if (v > threshold / size[find(i)]) return size[find(i)];
262+
vis[i] = true;
263+
}
264+
return -1;
265+
}
266+
267+
int find(int x) {
268+
if (p[x] != x) p[x] = find(p[x]);
269+
return p[x];
270+
}
271+
272+
void merge(int a, int b) {
273+
int pa = find(a), pb = find(b);
274+
if (pa == pb) return;
275+
p[pa] = pb;
276+
size[pb] += size[pa];
277+
}
278+
};
279+
```
280+
281+
```cpp
282+
class Solution {
283+
public:
284+
int validSubarraySize(vector<int>& nums, int threshold) {
285+
int n = nums.size();
286+
vector<int> left(n, -1);
287+
vector<int> right(n, n);
288+
stack<int> stk;
289+
for (int i = 0; i < n; ++i)
290+
{
291+
int v = nums[i];
292+
while (!stk.empty() && nums[stk.top()] >= v) stk.pop();
293+
if (!stk.empty()) left[i] = stk.top();
294+
stk.push(i);
295+
}
296+
stk = stack<int>();
297+
for (int i = n - 1; ~i; --i)
298+
{
299+
int v = nums[i];
300+
while (!stk.empty() && nums[stk.top()] >= v) stk.pop();
301+
if (!stk.empty()) right[i] = stk.top();
302+
stk.push(i);
303+
}
304+
for (int i = 0; i < n; ++i)
305+
{
306+
int v = nums[i];
307+
int k = right[i] - left[i] - 1;
308+
if (v > threshold / k) return k;
309+
}
310+
return -1;
311+
}
312+
};
313+
```
314+
315+
### **Go**
316+
317+
```go
318+
func validSubarraySize(nums []int, threshold int) int {
319+
n := len(nums)
320+
p := make([]int, n)
321+
size := make([]int, n)
322+
for i := range p {
323+
p[i] = i
324+
size[i] = 1
325+
}
326+
var find func(int) int
327+
find = func(x int) int {
328+
if p[x] != x {
329+
p[x] = find(p[x])
330+
}
331+
return p[x]
332+
}
333+
merge := func(a, b int) {
334+
pa, pb := find(a), find(b)
335+
if pa == pb {
336+
return
337+
}
338+
p[pa] = pb
339+
size[pb] += size[pa]
340+
}
341+
342+
arr := make([][]int, n)
343+
for i, v := range nums {
344+
arr[i] = []int{v, i}
345+
}
346+
sort.Slice(arr, func(i, j int) bool {
347+
return arr[i][0] > arr[j][0]
348+
})
349+
vis := make([]bool, n)
350+
for _, e := range arr {
351+
v, i := e[0], e[1]
352+
if i > 0 && vis[i-1] {
353+
merge(i, i-1)
354+
}
355+
if i < n-1 && vis[i+1] {
356+
merge(i, i+1)
357+
}
358+
if v > threshold/size[find(i)] {
359+
return size[find(i)]
360+
}
361+
vis[i] = true
362+
}
363+
return -1
364+
}
365+
```
64366

367+
```go
368+
func validSubarraySize(nums []int, threshold int) int {
369+
n := len(nums)
370+
left := make([]int, n)
371+
right := make([]int, n)
372+
for i := range left {
373+
left[i] = -1
374+
right[i] = n
375+
}
376+
var stk []int
377+
for i, v := range nums {
378+
for len(stk) > 0 && nums[stk[len(stk)-1]] >= v {
379+
stk = stk[:len(stk)-1]
380+
}
381+
if len(stk) > 0 {
382+
left[i] = stk[len(stk)-1]
383+
}
384+
stk = append(stk, i)
385+
}
386+
stk = []int{}
387+
for i := n - 1; i >= 0; i-- {
388+
v := nums[i]
389+
for len(stk) > 0 && nums[stk[len(stk)-1]] >= v {
390+
stk = stk[:len(stk)-1]
391+
}
392+
if len(stk) > 0 {
393+
right[i] = stk[len(stk)-1]
394+
}
395+
stk = append(stk, i)
396+
}
397+
for i, v := range nums {
398+
k := right[i] - left[i] - 1
399+
if v > threshold/k {
400+
return k
401+
}
402+
}
403+
return -1
404+
}
65405
```
66406

67407
### **TypeScript**

0 commit comments

Comments
 (0)