Skip to content

Commit 9b8fe07

Browse files
committed
feat: add solutions to lc problem: No.0845
No.0845.Longest Mountain in Array
1 parent fc29731 commit 9b8fe07

File tree

6 files changed

+469
-153
lines changed

6 files changed

+469
-153
lines changed

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

Lines changed: 202 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@
6060

6161
<!-- 这里可写通用的实现逻辑 -->
6262

63+
**方法一:预处理 + 枚举**
64+
65+
我们定义两个数组 $f$ 和 $g$,其中 $f[i]$ 表示以 $arr[i]$ 结尾的最长上升子序列的长度,而 $g[i]$ 表示以 $arr[i]$ 开头的最长下降子序列的长度。那么对于每个下标 $i$,如果 $f[i] \gt 1$ 且 $g[i] \gt 1$,那么以 $arr[i]$ 为山顶的山脉的长度为 $f[i] + g[i] - 1$,我们只需要枚举所有的 $i$,找出最大的那个值即可。
66+
67+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $arr$ 的长度。
68+
69+
**方法二:一次遍历(枚举左侧山脚)**
70+
71+
我们可以枚举山脉的左侧山脚,然后向右寻找山脉的右侧山脚。我们可以使用两个指针 $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$,继续寻找下一个山脉。
72+
73+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 $arr$ 的长度。
74+
6375
<!-- tabs:start -->
6476

6577
### **Python3**
@@ -69,32 +81,38 @@
6981
```python
7082
class Solution:
7183
def longestMountain(self, arr: List[int]) -> int:
72-
left, right = 0, 1
73-
status = -1
84+
n = len(arr)
85+
f = [1] * n
86+
g = [1] * n
87+
for i in range(1, n):
88+
if arr[i] > arr[i - 1]:
89+
f[i] = f[i - 1] + 1
7490
ans = 0
75-
while right < len(arr):
76-
if status == -1 or status == 1:
77-
if arr[right] == arr[right - 1]:
78-
status = -1
79-
if status == -1:
80-
if arr[right] > arr[right - 1]:
81-
status = 1
82-
else:
83-
left = right
84-
if status == 1 and arr[right] < arr[right - 1]:
85-
status = 2
86-
else:
87-
if arr[right] == arr[right - 1]:
88-
status = -1
89-
ans = max(ans, right - left)
90-
left = right
91-
elif arr[right] > arr[right - 1]:
92-
status = 1
93-
ans = max(ans, right - left)
94-
left = right - 1
95-
right += 1
96-
if status == 2:
97-
ans = max(right - left, ans)
91+
for i in range(n - 2, -1, -1):
92+
if arr[i] > arr[i + 1]:
93+
g[i] = g[i + 1] + 1
94+
if f[i] > 1:
95+
ans = max(ans, f[i] + g[i] - 1)
96+
return ans
97+
```
98+
99+
```python
100+
class Solution:
101+
def longestMountain(self, arr: List[int]) -> int:
102+
n = len(arr)
103+
ans = l = 0
104+
while l + 2 < n:
105+
r = l + 1
106+
if arr[l] < arr[r]:
107+
while r + 1 < n and arr[r] < arr[r + 1]:
108+
r += 1
109+
if r < n - 1 and arr[r] > arr[r + 1]:
110+
while r < n - 1 and arr[r] > arr[r + 1]:
111+
r += 1
112+
ans = max(ans, r - l + 1)
113+
else:
114+
r += 1
115+
l = r
98116
return ans
99117
```
100118

@@ -105,41 +123,175 @@ class Solution:
105123
```java
106124
class Solution {
107125
public int longestMountain(int[] arr) {
108-
int left = 0, right = 0;
126+
int n = arr.length;
127+
int[] f = new int[n];
128+
int[] g = new int[n];
129+
Arrays.fill(f, 1);
130+
Arrays.fill(g, 1);
131+
for (int i = 1; i < n; ++i) {
132+
if (arr[i] > arr[i - 1]) {
133+
f[i] = f[i - 1] + 1;
134+
}
135+
}
109136
int ans = 0;
110-
int status = -1;
111-
while (++right < arr.length) {
112-
if (status == -1 || status == 1) {
113-
if (arr[right] == arr[right - 1]) {
114-
status = -1;
137+
for (int i = n - 2; i >= 0; --i) {
138+
if (arr[i] > arr[i + 1]) {
139+
g[i] = g[i + 1] + 1;
140+
if (f[i] > 1) {
141+
ans = Math.max(ans, f[i] + g[i] - 1);
115142
}
116-
if (status == -1) {
117-
if (arr[right] > arr[right - 1]) {
118-
status = 1;
119-
} else {
120-
left = right;
121-
}
143+
}
144+
}
145+
return ans;
146+
}
147+
}
148+
```
149+
150+
```java
151+
class Solution {
152+
public int longestMountain(int[] arr) {
153+
int n = arr.length;
154+
int ans = 0;
155+
for (int l = 0, r = 0; l + 2 < n; l = r) {
156+
r = l + 1;
157+
if (arr[l] < arr[r]) {
158+
while (r + 1 < n && arr[r] < arr[r + 1]) {
159+
++r;
122160
}
123-
if (status == 1 && arr[right] < arr[right - 1]) {
124-
status = 2;
161+
if (r + 1 < n && arr[r] > arr[r + 1]) {
162+
while (r + 1 < n && arr[r] > arr[r + 1]) {
163+
++r;
164+
}
165+
ans = Math.max(ans, r - l + 1);
166+
} else {
167+
++r;
125168
}
126-
} else {
127-
if (arr[right] > arr[right - 1]) {
128-
status = 1;
129-
ans = Math.max(right - left, ans);
130-
left = right - 1;
131-
} else if (arr[right] == arr[right - 1]) {
132-
status = -1;
133-
ans = Math.max(right - left, ans);
134-
left = right;
169+
}
170+
}
171+
return ans;
172+
}
173+
}
174+
```
175+
176+
### **C++**
177+
178+
```cpp
179+
class Solution {
180+
public:
181+
int longestMountain(vector<int>& arr) {
182+
int n = arr.size();
183+
int f[n];
184+
int g[n];
185+
fill(f, f + n, 1);
186+
fill(g, g + n, 1);
187+
for (int i = 1; i < n; ++i) {
188+
if (arr[i] > arr[i - 1]) {
189+
f[i] = f[i - 1] + 1;
190+
}
191+
}
192+
int ans = 0;
193+
for (int i = n - 2; ~i; --i) {
194+
if (arr[i] > arr[i + 1]) {
195+
g[i] = g[i + 1] + 1;
196+
if (f[i] > 1) {
197+
ans = max(ans, f[i] + g[i] - 1);
135198
}
136199
}
137200
}
138-
if (status == 2) {
139-
ans = Math.max(ans, right - left);
201+
return ans;
202+
}
203+
};
204+
```
205+
206+
```cpp
207+
class Solution {
208+
public:
209+
int longestMountain(vector<int>& arr) {
210+
int n = arr.size();
211+
int ans = 0;
212+
for (int l = 0, r = 0; l + 2 < n; l = r) {
213+
r = l + 1;
214+
if (arr[l] < arr[r]) {
215+
while (r + 1 < n && arr[r] < arr[r + 1]) {
216+
++r;
217+
}
218+
if (r + 1 < n && arr[r] > arr[r + 1]) {
219+
while (r + 1 < n && arr[r] > arr[r + 1]) {
220+
++r;
221+
}
222+
ans = max(ans, r - l + 1);
223+
} else {
224+
++r;
225+
}
226+
}
140227
}
141228
return ans;
142229
}
230+
};
231+
```
232+
233+
### **Go**
234+
235+
```go
236+
func longestMountain(arr []int) (ans int) {
237+
n := len(arr)
238+
f := make([]int, n)
239+
g := make([]int, n)
240+
for i := range f {
241+
f[i] = 1
242+
g[i] = 1
243+
}
244+
for i := 1; i < n; i++ {
245+
if arr[i] > arr[i-1] {
246+
f[i] = f[i-1] + 1
247+
}
248+
}
249+
for i := n - 2; i >= 0; i-- {
250+
if arr[i] > arr[i+1] {
251+
g[i] = g[i+1] + 1
252+
if f[i] > 1 {
253+
ans = max(ans, f[i]+g[i]-1)
254+
}
255+
}
256+
}
257+
return
258+
}
259+
260+
func max(a, b int) int {
261+
if a > b {
262+
return a
263+
}
264+
return b
265+
}
266+
```
267+
268+
```go
269+
func longestMountain(arr []int) (ans int) {
270+
n := len(arr)
271+
for l, r := 0, 0; l+2 < n; l = r {
272+
r = l + 1
273+
if arr[l] < arr[r] {
274+
for r+1 < n && arr[r] < arr[r+1] {
275+
r++
276+
}
277+
if r+1 < n && arr[r] > arr[r+1] {
278+
for r+1 < n && arr[r] > arr[r+1] {
279+
r++
280+
}
281+
ans = max(ans, r-l+1)
282+
} else {
283+
r++
284+
}
285+
}
286+
}
287+
return
288+
}
289+
290+
func max(a, b int) int {
291+
if a > b {
292+
return a
293+
}
294+
return b
143295
}
144296
```
145297

0 commit comments

Comments
 (0)