Skip to content

Commit 291f917

Browse files
authored
feat: add solutions to lc problem: No.0845 (doocs#4866)
1 parent 8a39fca commit 291f917

File tree

4 files changed

+154
-3
lines changed

4 files changed

+154
-3
lines changed

solution/0800-0899/0845.Longest Mountain in Array/README.md

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,31 @@ func longestMountain(arr []int) (ans int) {
190190
}
191191
```
192192

193+
#### TypeScript
194+
195+
```ts
196+
function longestMountain(arr: number[]): number {
197+
const n = arr.length;
198+
const f: number[] = Array(n).fill(1);
199+
const g: number[] = Array(n).fill(1);
200+
for (let i = 1; i < n; ++i) {
201+
if (arr[i] > arr[i - 1]) {
202+
f[i] = f[i - 1] + 1;
203+
}
204+
}
205+
let ans = 0;
206+
for (let i = n - 2; i >= 0; --i) {
207+
if (arr[i] > arr[i + 1]) {
208+
g[i] = g[i + 1] + 1;
209+
if (f[i] > 1) {
210+
ans = Math.max(ans, f[i] + g[i] - 1);
211+
}
212+
}
213+
}
214+
return ans;
215+
}
216+
```
217+
193218
<!-- tabs:end -->
194219

195220
<!-- solution:end -->
@@ -200,7 +225,7 @@ func longestMountain(arr []int) (ans int) {
200225

201226
我们可以枚举山脉的左侧山脚,然后向右寻找山脉的右侧山脚。我们可以使用两个指针 $l$ 和 $r$,其中 $l$ 表示左侧山脚的下标,$r$ 表示右侧山脚的下标,初始时 $l=0$,$r=0$,然后我们向右移动 $r$,找到山顶的位置,此时判断 $r$ 是否满足 $r + 1 \lt n$ 并且 $arr[r] \gt arr[r + 1]$,如果满足,我们向右继续移动 $r$,直到找到右侧山脚的位置,此时山脉的长度为 $r - l + 1$,我们更新答案,然后将 $l$ 的值更新为 $r$,继续寻找下一个山脉。
202227

203-
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $arr$ 的长度。
228+
时间复杂度 $O(n)$,其中 $n$ 为数组 $arr$ 的长度。空间复杂度 $O(1)$
204229

205230
<!-- tabs:start -->
206231

@@ -308,6 +333,32 @@ func longestMountain(arr []int) (ans int) {
308333
}
309334
```
310335

336+
#### TypeScript
337+
338+
```ts
339+
function longestMountain(arr: number[]): number {
340+
const n = arr.length;
341+
let ans = 0;
342+
for (let l = 0, r = 0; l + 2 < n; l = r) {
343+
r = l + 1;
344+
if (arr[l] < arr[r]) {
345+
while (r + 1 < n && arr[r] < arr[r + 1]) {
346+
++r;
347+
}
348+
if (r + 1 < n && arr[r] > arr[r + 1]) {
349+
while (r + 1 < n && arr[r] > arr[r + 1]) {
350+
++r;
351+
}
352+
ans = Math.max(ans, r - l + 1);
353+
} else {
354+
++r;
355+
}
356+
}
357+
}
358+
return ans;
359+
}
360+
```
361+
311362
<!-- tabs:end -->
312363

313364
<!-- solution:end -->

solution/0800-0899/0845.Longest Mountain in Array/README_EN.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ tags:
7272

7373
<!-- solution:start -->
7474

75-
### Solution 1
75+
## Solution 1: Preprocessing + Enumeration
76+
77+
We define two arrays $f$ and $g$, where $f[i]$ represents the length of the longest increasing subsequence ending at $arr[i]$, and $g[i]$ represents the length of the longest decreasing subsequence starting at $arr[i]$. Then for each index $i$, if $f[i] \gt 1$ and $g[i] \gt 1$, the length of the mountain with $arr[i]$ as the peak is $f[i] + g[i] - 1$. We only need to enumerate all $i$ and find the maximum value.
78+
79+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $arr$.
7680

7781
<!-- tabs:start -->
7882

@@ -183,13 +187,42 @@ func longestMountain(arr []int) (ans int) {
183187
}
184188
```
185189

190+
#### TypeScript
191+
192+
```ts
193+
function longestMountain(arr: number[]): number {
194+
const n = arr.length;
195+
const f: number[] = Array(n).fill(1);
196+
const g: number[] = Array(n).fill(1);
197+
for (let i = 1; i < n; ++i) {
198+
if (arr[i] > arr[i - 1]) {
199+
f[i] = f[i - 1] + 1;
200+
}
201+
}
202+
let ans = 0;
203+
for (let i = n - 2; i >= 0; --i) {
204+
if (arr[i] > arr[i + 1]) {
205+
g[i] = g[i + 1] + 1;
206+
if (f[i] > 1) {
207+
ans = Math.max(ans, f[i] + g[i] - 1);
208+
}
209+
}
210+
}
211+
return ans;
212+
}
213+
```
214+
186215
<!-- tabs:end -->
187216

188217
<!-- solution:end -->
189218

190219
<!-- solution:start -->
191220

192-
### Solution 2
221+
## Solution 2: One Pass (Enumerate Left Base of Mountain)
222+
223+
We can enumerate the left base of the mountain and then search to the right for the right base of the mountain. We can use two pointers $l$ and $r$, where $l$ represents the index of the left base and $r$ represents the index of the right base. Initially, $l=0$ and $r=0$. Then we move $r$ to the right to find the position of the peak. At this point, we check if $r$ satisfies $r + 1 \lt n$ and $arr[r] \gt arr[r + 1]$. If so, we continue moving $r$ to the right until we find the position of the right base. At this point, the length of the mountain is $r - l + 1$. We update the answer and then update the value of $l$ to $r$, continuing to search for the next mountain.
224+
225+
The time complexity is $O(n)$, where $n$ is the length of the array $arr$. The space complexity is $O(1)$.
193226

194227
<!-- tabs:start -->
195228

@@ -297,6 +330,32 @@ func longestMountain(arr []int) (ans int) {
297330
}
298331
```
299332

333+
#### TypeScript
334+
335+
```ts
336+
function longestMountain(arr: number[]): number {
337+
const n = arr.length;
338+
let ans = 0;
339+
for (let l = 0, r = 0; l + 2 < n; l = r) {
340+
r = l + 1;
341+
if (arr[l] < arr[r]) {
342+
while (r + 1 < n && arr[r] < arr[r + 1]) {
343+
++r;
344+
}
345+
if (r + 1 < n && arr[r] > arr[r + 1]) {
346+
while (r + 1 < n && arr[r] > arr[r + 1]) {
347+
++r;
348+
}
349+
ans = Math.max(ans, r - l + 1);
350+
} else {
351+
++r;
352+
}
353+
}
354+
}
355+
return ans;
356+
}
357+
```
358+
300359
<!-- tabs:end -->
301360

302361
<!-- solution:end -->
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function longestMountain(arr: number[]): number {
2+
const n = arr.length;
3+
const f: number[] = Array(n).fill(1);
4+
const g: number[] = Array(n).fill(1);
5+
for (let i = 1; i < n; ++i) {
6+
if (arr[i] > arr[i - 1]) {
7+
f[i] = f[i - 1] + 1;
8+
}
9+
}
10+
let ans = 0;
11+
for (let i = n - 2; i >= 0; --i) {
12+
if (arr[i] > arr[i + 1]) {
13+
g[i] = g[i + 1] + 1;
14+
if (f[i] > 1) {
15+
ans = Math.max(ans, f[i] + g[i] - 1);
16+
}
17+
}
18+
}
19+
return ans;
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
function longestMountain(arr: number[]): number {
2+
const n = arr.length;
3+
let ans = 0;
4+
for (let l = 0, r = 0; l + 2 < n; l = r) {
5+
r = l + 1;
6+
if (arr[l] < arr[r]) {
7+
while (r + 1 < n && arr[r] < arr[r + 1]) {
8+
++r;
9+
}
10+
if (r + 1 < n && arr[r] > arr[r + 1]) {
11+
while (r + 1 < n && arr[r] > arr[r + 1]) {
12+
++r;
13+
}
14+
ans = Math.max(ans, r - l + 1);
15+
} else {
16+
++r;
17+
}
18+
}
19+
}
20+
return ans;
21+
}

0 commit comments

Comments
 (0)