Skip to content

Commit

Permalink
feat: add ts solution to lc problem: No.1793 (#1913)
Browse files Browse the repository at this point in the history
No.1793.Maximum Score of a Good Subarray
  • Loading branch information
yanglbme authored Nov 1, 2023
1 parent 4a5c1c5 commit e320a9f
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 3 deletions.
41 changes: 39 additions & 2 deletions solution/1700-1799/1793.Maximum Score of a Good Subarray/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@

**方法一:单调栈**

我们可以枚举 `nums` 中的每个元素 $nums[i]$ 作为子数组的最小值,利用单调栈找出其左边第一个小于 $nums[i]$ 的位置 $left[i]$ 和右边第一个小于等于 $nums[i]$ 的位置 $right[i]$,则以 $nums[i]$ 为最小值的子数组的分数为 $nums[i] \times (right[i] - left[i] - 1)$。
我们可以枚举 $nums$ 中的每个元素 $nums[i]$ 作为子数组的最小值,利用单调栈找出其左边第一个小于 $nums[i]$ 的位置 $left[i]$ 和右边第一个小于等于 $nums[i]$ 的位置 $right[i]$,则以 $nums[i]$ 为最小值的子数组的分数为 $nums[i] \times (right[i] - left[i] - 1)$。

需要注意的是,只有当左右边界 $left[i]$ 和 $right[i]$ 满足 $left[i]+1 \leq k \leq right[i]-1$ 时,答案才有可能更新。

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

<!-- tabs:start -->

Expand Down Expand Up @@ -212,6 +212,43 @@ func maximumScore(nums []int, k int) (ans int) {
}
```

### **TypeScript**

```ts
function maximumScore(nums: number[], k: number): number {
const n = nums.length;
const left: number[] = Array(n).fill(-1);
const right: number[] = Array(n).fill(n);
const stk: number[] = [];
for (let i = 0; i < n; ++i) {
while (stk.length && nums[stk.at(-1)] >= nums[i]) {
stk.pop();
}
if (stk.length) {
left[i] = stk.at(-1);
}
stk.push(i);
}
stk.length = 0;
for (let i = n - 1; ~i; --i) {
while (stk.length && nums[stk.at(-1)] > nums[i]) {
stk.pop();
}
if (stk.length) {
right[i] = stk.at(-1);
}
stk.push(i);
}
let ans = 0;
for (let i = 0; i < n; ++i) {
if (left[i] + 1 <= k && k <= right[i] - 1) {
ans = Math.max(ans, nums[i] * (right[i] - left[i] - 1));
}
}
return ans;
}
```

### **...**

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@

## Solutions

**Solution 1: Monotonic Stack**

We can enumerate each element $nums[i]$ in $nums$ as the minimum value of the subarray, and use a monotonic stack to find the first position $left[i]$ on the left that is less than $nums[i]$ and the first position $right[i]$ on the right that is less than or equal to $nums[i]$. Then, the score of the subarray with $nums[i]$ as the minimum value is $nums[i] \times (right[i] - left[i] - 1)$.

It should be noted that the answer can only be updated when the left and right boundaries $left[i]$ and $right[i]$ satisfy $left[i]+1 \leq k \leq right[i]-1$.

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

<!-- tabs:start -->

### **Python3**
Expand Down Expand Up @@ -196,6 +204,43 @@ func maximumScore(nums []int, k int) (ans int) {
}
```

### **TypeScript**

```ts
function maximumScore(nums: number[], k: number): number {
const n = nums.length;
const left: number[] = Array(n).fill(-1);
const right: number[] = Array(n).fill(n);
const stk: number[] = [];
for (let i = 0; i < n; ++i) {
while (stk.length && nums[stk.at(-1)] >= nums[i]) {
stk.pop();
}
if (stk.length) {
left[i] = stk.at(-1);
}
stk.push(i);
}
stk.length = 0;
for (let i = n - 1; ~i; --i) {
while (stk.length && nums[stk.at(-1)] > nums[i]) {
stk.pop();
}
if (stk.length) {
right[i] = stk.at(-1);
}
stk.push(i);
}
let ans = 0;
for (let i = 0; i < n; ++i) {
if (left[i] + 1 <= k && k <= right[i] - 1) {
ans = Math.max(ans, nums[i] * (right[i] - left[i] - 1));
}
}
return ans;
}
```

### **...**

```
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
function maximumScore(nums: number[], k: number): number {
const n = nums.length;
const left: number[] = Array(n).fill(-1);
const right: number[] = Array(n).fill(n);
const stk: number[] = [];
for (let i = 0; i < n; ++i) {
while (stk.length && nums[stk.at(-1)] >= nums[i]) {
stk.pop();
}
if (stk.length) {
left[i] = stk.at(-1);
}
stk.push(i);
}
stk.length = 0;
for (let i = n - 1; ~i; --i) {
while (stk.length && nums[stk.at(-1)] > nums[i]) {
stk.pop();
}
if (stk.length) {
right[i] = stk.at(-1);
}
stk.push(i);
}
let ans = 0;
for (let i = 0; i < n; ++i) {
if (left[i] + 1 <= k && k <= right[i] - 1) {
ans = Math.max(ans, nums[i] * (right[i] - left[i] - 1));
}
}
return ans;
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@

题目实际上要我们找到一个最小的下标 $i$ 和一个最大的下标 $j$,使得 $firstString[i]$ 与 $secondString[j]$ 相等,且 $i - j$ 的值是所有满足条件的下标对中最小的。

因此,我们先用哈希表 `last` 记录 $secondString$ 中每个字符最后一次出现的下标,然后遍历 $firstString$,对于每个字符 $c$,如果 $c$ 在 $secondString$ 中出现过,则计算 $i - last[c]$,如果 $i - last[c]$ 的值小于当前最小值,则更新最小值,同时更新答案为 1;如果 $i - last[c]$ 的值等于当前最小值,则答案加 1。
因此,我们先用哈希表 $last$ 记录 $secondString$ 中每个字符最后一次出现的下标,然后遍历 $firstString$,对于每个字符 $c$,如果 $c$ 在 $secondString$ 中出现过,则计算 $i - last[c]$,如果 $i - last[c]$ 的值小于当前最小值,则更新最小值,同时更新答案为 1;如果 $i - last[c]$ 的值等于当前最小值,则答案加 1。

时间复杂度 $O(m + n)$,空间复杂度 $O(C)$。其中 $m$ 和 $n$ 分别是 $firstString$ 和 $secondString$ 的长度,而 $C$ 是字符集的大小。本题中 $C = 26$。

Expand Down

0 comments on commit e320a9f

Please sign in to comment.