Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

feat: add ts solution to lc problem: No.1793 #1913

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

Merged
merged 1 commit into from
Nov 1, 2023
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
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