Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problems: No.3113~3115 #2585

Merged
merged 1 commit into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,116 @@

## 解法

### 方法一
### 方法一:单调栈

我们考虑以数组 $nums$ 中的每个元素 $x$ 作为子数组的边界元素且最大值的情况。

每个长度为 $1$ 的子数组都满足条件,而对于长度大于 $1$ 的子数组,子数组中的所有元素都不能大于边界元素 $x$,我们可以用单调栈来实现。

我们维护一个从栈底到栈顶单调递减的栈,单调栈的每个元素是一个二元组 $[x, cnt]$,表示元素 $x$ 且以 $x$ 为边界元素且最大值的子数组的个数为 $cnt$。

我们从左到右遍历数组 $nums$,对于每个元素 $x$,我们不断地将栈顶元素弹出,直到栈为空或者栈顶元素的第一个元素大于等于 $x$。如果栈为空,或者栈顶元素的第一个元素大于 $x$,说明当前遇到第一个边界元素为 $x$ 且最大值的子数组,该子数组的长度为 $1$,所以我们将 $[x, 1]$ 入栈。如果栈顶元素的第一个元素等于 $x$,说明当前遇到的边界元素为 $x$ 且最大值的子数组,我们将栈顶元素的第二个元素加 $1$。然后,我们将栈顶元素的第二个元素加到答案中。

遍历结束后,返回答案即可。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。

<!-- tabs:start -->

```python

class Solution:
def numberOfSubarrays(self, nums: List[int]) -> int:
stk = []
ans = 0
for x in nums:
while stk and stk[-1][0] < x:
stk.pop()
if not stk or stk[-1][0] > x:
stk.append([x, 1])
else:
stk[-1][1] += 1
ans += stk[-1][1]
return ans
```

```java

class Solution {
public long numberOfSubarrays(int[] nums) {
Deque<int[]> stk = new ArrayDeque<>();
long ans = 0;
for (int x : nums) {
while (!stk.isEmpty() && stk.peek()[0] < x) {
stk.pop();
}
if (stk.isEmpty() || stk.peek()[0] > x) {
stk.push(new int[] {x, 1});
} else {
stk.peek()[1]++;
}
ans += stk.peek()[1];
}
return ans;
}
}
```

```cpp

class Solution {
public:
long long numberOfSubarrays(vector<int>& nums) {
vector<pair<int, int>> stk;
long long ans = 0;
for (int x : nums) {
while (!stk.empty() && stk.back().first < x) {
stk.pop_back();
}
if (stk.empty() || stk.back().first > x) {
stk.push_back(make_pair(x, 1));
} else {
stk.back().second++;
}
ans += stk.back().second;
}
return ans;
}
};
```

```go
func numberOfSubarrays(nums []int) (ans int64) {
stk := [][2]int{}
for _, x := range nums {
for len(stk) > 0 && stk[len(stk)-1][0] < x {
stk = stk[:len(stk)-1]
}
if len(stk) == 0 || stk[len(stk)-1][0] > x {
stk = append(stk, [2]int{x, 1})
} else {
stk[len(stk)-1][1]++
}
ans += int64(stk[len(stk)-1][1])
}
return
}
```

```ts
function numberOfSubarrays(nums: number[]): number {
const stk: number[][] = [];
let ans = 0;
for (const x of nums) {
while (stk.length > 0 && stk.at(-1)![0] < x) {
stk.pop();
}
if (stk.length === 0 || stk.at(-1)![0] > x) {
stk.push([x, 1]);
} else {
stk.at(-1)![1]++;
}
ans += stk.at(-1)![1];
}
return ans;
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,116 @@

## Solutions

### Solution 1
### Solution 1: Monotonic Stack

We consider each element $x$ in the array $nums$ as the boundary element and the maximum value of the subarray.

Each subarray of length $1$ meets the condition, and for subarrays with length greater than $1$, all elements in the subarray cannot be greater than the boundary element $x$. We can implement this with a monotonic stack.

We maintain a stack that decreases monotonically from the bottom to the top. Each element in the monotonic stack is a pair $[x, cnt]$, representing the element $x$ and the count $cnt$ of subarrays with $x$ as the boundary element and the maximum value.

We traverse the array $nums$ from left to right. For each element $x$, we continuously pop the top element of the stack until the stack is empty or the first element of the top element of the stack is greater than or equal to $x$. If the stack is empty, or the first element of the top element of the stack is greater than $x$, it means that we have encountered the first subarray with $x$ as the boundary element and the maximum value, and the length of this subarray is $1$, so we push $[x, 1]$ into the stack. If the first element of the top element of the stack is equal to $x$, it means that we have encountered a subarray with $x$ as the boundary element and the maximum value, and we add $1$ to the second element of the top element of the stack. Then, we add the second element of the top element of the stack to the answer.

After the traversal, we return the answer.

The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $nums$.

<!-- tabs:start -->

```python

class Solution:
def numberOfSubarrays(self, nums: List[int]) -> int:
stk = []
ans = 0
for x in nums:
while stk and stk[-1][0] < x:
stk.pop()
if not stk or stk[-1][0] > x:
stk.append([x, 1])
else:
stk[-1][1] += 1
ans += stk[-1][1]
return ans
```

```java

class Solution {
public long numberOfSubarrays(int[] nums) {
Deque<int[]> stk = new ArrayDeque<>();
long ans = 0;
for (int x : nums) {
while (!stk.isEmpty() && stk.peek()[0] < x) {
stk.pop();
}
if (stk.isEmpty() || stk.peek()[0] > x) {
stk.push(new int[] {x, 1});
} else {
stk.peek()[1]++;
}
ans += stk.peek()[1];
}
return ans;
}
}
```

```cpp

class Solution {
public:
long long numberOfSubarrays(vector<int>& nums) {
vector<pair<int, int>> stk;
long long ans = 0;
for (int x : nums) {
while (!stk.empty() && stk.back().first < x) {
stk.pop_back();
}
if (stk.empty() || stk.back().first > x) {
stk.push_back(make_pair(x, 1));
} else {
stk.back().second++;
}
ans += stk.back().second;
}
return ans;
}
};
```

```go
func numberOfSubarrays(nums []int) (ans int64) {
stk := [][2]int{}
for _, x := range nums {
for len(stk) > 0 && stk[len(stk)-1][0] < x {
stk = stk[:len(stk)-1]
}
if len(stk) == 0 || stk[len(stk)-1][0] > x {
stk = append(stk, [2]int{x, 1})
} else {
stk[len(stk)-1][1]++
}
ans += int64(stk[len(stk)-1][1])
}
return
}
```

```ts
function numberOfSubarrays(nums: number[]): number {
const stk: number[][] = [];
let ans = 0;
for (const x of nums) {
while (stk.length > 0 && stk.at(-1)![0] < x) {
stk.pop();
}
if (stk.length === 0 || stk.at(-1)![0] > x) {
stk.push([x, 1]);
} else {
stk.at(-1)![1]++;
}
ans += stk.at(-1)![1];
}
return ans;
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Solution {
public:
long long numberOfSubarrays(vector<int>& nums) {
vector<pair<int, int>> stk;
long long ans = 0;
for (int x : nums) {
while (!stk.empty() && stk.back().first < x) {
stk.pop_back();
}
if (stk.empty() || stk.back().first > x) {
stk.push_back(make_pair(x, 1));
} else {
stk.back().second++;
}
ans += stk.back().second;
}
return ans;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
func numberOfSubarrays(nums []int) (ans int64) {
stk := [][2]int{}
for _, x := range nums {
for len(stk) > 0 && stk[len(stk)-1][0] < x {
stk = stk[:len(stk)-1]
}
if len(stk) == 0 || stk[len(stk)-1][0] > x {
stk = append(stk, [2]int{x, 1})
} else {
stk[len(stk)-1][1]++
}
ans += int64(stk[len(stk)-1][1])
}
return
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Solution {
public long numberOfSubarrays(int[] nums) {
Deque<int[]> stk = new ArrayDeque<>();
long ans = 0;
for (int x : nums) {
while (!stk.isEmpty() && stk.peek()[0] < x) {
stk.pop();
}
if (stk.isEmpty() || stk.peek()[0] > x) {
stk.push(new int[] {x, 1});
} else {
stk.peek()[1]++;
}
ans += stk.peek()[1];
}
return ans;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Solution:
def numberOfSubarrays(self, nums: List[int]) -> int:
stk = []
ans = 0
for x in nums:
while stk and stk[-1][0] < x:
stk.pop()
if not stk or stk[-1][0] > x:
stk.append([x, 1])
else:
stk[-1][1] += 1
ans += stk[-1][1]
return ans
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function numberOfSubarrays(nums: number[]): number {
const stk: number[][] = [];
let ans = 0;
for (const x of nums) {
while (stk.length > 0 && stk.at(-1)![0] < x) {
stk.pop();
}
if (stk.length === 0 || stk.at(-1)![0] > x) {
stk.push([x, 1]);
} else {
stk.at(-1)![1]++;
}
ans += stk.at(-1)![1];
}
return ans;
}
Loading
Loading