[LeetCode] Longest Mountain in Array 数组中最长的山
Let's call any (contiguous) subarray B (of A) a mountain if the following properties hold:
B.length >= 3- There exists some
0 < i < B.length - 1such thatB[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]
(Note that B could be any subarray of A, including the entire array A.)
Given an array A of integers, return the length of the longest mountain.
Return 0 if there is no mountain.
Example 1:
Input: [2,1,4,7,3,2,5]
Output: 5
Explanation: The largest mountain is [1,4,7,3,2] which has length 5.
Example 2:
Input: [2,2,2]
Output: 0
Explanation: There is no mountain.
Note:
0 <= A.length <= 100000 <= A[i] <= 10000
Follow up:
- Can you solve it using only one pass?
- Can you solve it in
O(1)space?
这道题给了我们一个数组,然后定义了一种像山一样的子数组,就是先递增再递减的子数组,注意这里是强行递增或者递减的,并不存在相等的情况。那么实际上这道题就是让在数组中寻找一个位置,使得以此位置为终点的递增数组和以此位置为起点的递减数组的长度最大。而以某个位置为起点的递减数组,如果反个方向来看,其实就是就该位置为终点的递增数列,那么既然都是求最长的递增数列,我们可以分别用两个 dp 数组 up 和 down,其中 up[i] 表示以 i 位置为终点的最长递增数列的个数,down[i] 表示以 i 位置为起点的最长递减数列的个数,这样我们正向更新 up 数组,反向更新 down 数组即可。先反向更新好了 down 之后,在正向更新 up 数组的同时,也可以更新结果 res,当某个位置的 up[i] 和 down[i] 均大于0的时候,那么就可以用 up[i] + down[i] + 1 来更新结果 res 了,参见代码如下:
解法一:
class Solution {
public:
int longestMountain(vector<int>& A) {
int res = , n = A.size();
vector<int> up(n), down(n);
for (int i = n - ; i >= ; --i) {
if (A[i] > A[i + ]) down[i] = down[i + ] + ;
}
for (int i = ; i < n; ++i) {
if (A[i] > A[i - ]) up[i] = up[i - ] + ;
if (up[i] > && down[i] > ) res = max(res, up[i] + down[i] + );
}
return res;
}
};
我们可以对空间进行优化,不必使用两个数组来记录所有位置的信息,而是只用两个变量 up 和 down 来分别记录以当前位置为终点的最长递增数列的长度,和以当前位置为终点的最长递减数列的长度。 我们从 i=1 的位置开始遍历,因为山必须要有上坡和下坡,所以 i=0 的位置永远不可能成为 peak。此时再看,如果当前位置跟前面的位置相等了,那么当前位置的 up 和 down 都要重置为0,从当前位置开始找新的山,和之前的应该断开。或者是当 down 不为0,说明此时是在下坡,如果当前位置大于之前的了,突然变上坡了,那么之前的累计也需要重置为0。然后当前位置再进行判断,若大于前一个位置,则是上坡,up 自增1,若小于前一个位置,是下坡,down 自增1。当 up 和 down 同时为正数,则用 up+down+1 来更新结果 res 即可,参见代码如下:
解法二:
class Solution {
public:
int longestMountain(vector<int>& A) {
int res = , up = , down = , n = A.size();
for (int i = ; i < n; ++i) {
if ((down && A[i - ] < A[i]) || (A[i - ] == A[i])) {
up = down = ;
}
if (A[i - ] < A[i]) ++up;
if (A[i - ] > A[i]) ++down;
if (up > && down > ) res = max(res, up + down + );
}
return res;
}
};
我们可以换一种思路,还是一次遍历就行,进行 while 循环,条件是 i < n-1,然后判断,当前数字大于等于下一个数字则跳过,因为我们希望首先上坡,当找到递增的起点i后,则再开始循环,找山顶 peak,找到了之后,再进行下坡,找到山脚j,这样如果i,peak,和j都不相同的话,说明找到了一个完整的山,用 j-i+1 来更新结果 res 即可,然后i从j开始继续遍历,参见代码如下:
解法三:
class Solution {
public:
int longestMountain(vector<int>& A) {
int res = , i = , n = A.size();
while (i < n - ) {
while (i < n - && A[i] >= A[i + ]) ++i;
int peak = i;
while (peak < n - && A[peak] < A[peak + ]) ++peak;
int j = peak;
while (j < n - && A[j] > A[j + ]) ++j;
if (i < peak && peak < j) res = max(res, j - i + );
i = j;
}
return res;
}
};
也可以再换种思路,首先来找山峰,peak 的范围是 [1, n-1],因为首尾两个数字都不能做山峰,能做山峰的位置上的数必须大于其左右两边的数字,然后分别向左右两个方向遍历,这样就可以找到完整的山,用 right-left+1 来更新结果 res,参见代码如下:
解法四:
class Solution {
public:
int longestMountain(vector<int>& A) {
int res = , n = A.size();
for (int i = ; i < n - ; ++i) {
if (A[i - ] < A[i] && A[i + ] < A[i]) {
int left = i - , right = i + ;
while (left > && A[left - ] < A[left]) --left;
while (right < n - && A[right] > A[right + ]) ++right;
res = max(res, right - left + );
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/845
参考资料:
https://leetcode.com/problems/longest-mountain-in-array/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Longest Mountain in Array 数组中最长的山的更多相关文章
- Longest Mountain in Array 数组中的最长山脉
我们把数组 A 中符合下列属性的任意连续子数组 B 称为 “山脉”: B.length >= 3 存在 0 < i < B.length - 1 使得 B[0] < B[1] ...
- 【LeetCode】845. Longest Mountain in Array 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双数组 参考资料 日期 题目地址:https://l ...
- LeetCode第十四题-字符串数组中最长的共同前缀
Longest Common Prefix 问题简介: 编写一个函数来查找字符串数组中最长的公共前缀字符串,如果没有公共前缀,则返回空字符串"" 举例: 1: 输入: [“xwq” ...
- 014 Longest Common Prefix 查找字符串数组中最长的公共前缀字符串
编写一个函数来查找字符串数组中最长的公共前缀字符串. 详见:https://leetcode.com/problems/longest-common-prefix/description/ 实现语言: ...
- LeetCode:寻找旋转排序数组中的最小值【153】
LeetCode:寻找旋转排序数组中的最小值[153] 题目描述 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0 ...
- [Swift]LeetCode845. 数组中的最长山脉 | Longest Mountain in Array
Let's call any (contiguous) subarray B (of A) a mountain if the following properties hold: B.length ...
- [LeetCode] Kth Largest Element in an Array 数组中第k大的数字
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- [LeetCode] K-diff Pairs in an Array 数组中差为K的数对
Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in t ...
- [LeetCode] 215. Kth Largest Element in an Array 数组中第k大的数字
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
随机推荐
- mysql性能优化分析 --- 下篇
概要回顾 之前看过<高性能mysql>对mysql数据库有了系统化的理解,虽然没能达到精通,但有了概念,遇到问题时会有逻辑条理的分析; 这回继上次sql分析结果的一个继续延伸分析,我拿了; ...
- 吴恩达《机器学习》编程作业——machine-learning-ex1:线性回归
❄❄❄❄❄❄❄❄[回到目录]❄❄❄❄❄❄❄❄ 本次编程作业中,需要完成的代码有如下几部分: [⋆] warmUpExercise.m - Simple example function in Octa ...
- MySQL1:客户端/服务器架构
一.MySQL的客户端/服务器架构 前言 之前对MySQL的认知只限于会写些SQL,本篇算是笔记,记录和整理下自己对MySQL不熟悉的地方. 大致逻辑: MySQL的服务器程序直接和我们存储的数据打交 ...
- 【转】一文掌握 Linux 性能分析之网络篇(续)
[转]一文掌握 Linux 性能分析之网络篇(续) 在上篇网络篇中,我们已经介绍了几个 Linux 网络方向的性能分析工具,本文再补充几个.总结下来,余下的工具包括但不限于以下几个: sar:统计信息 ...
- shell利用mysql表项的icmp检测
作者:邓聪聪 利用mysql的表项记录IP地址和对应状态 +----+-----------------+--------+--------+ | id | ip_host | desc | stat ...
- 生活英语读写MOOC-Literature Tutor-有声名著阅读推荐
生活英语读写MOOC-Literature Tutor-有声名著阅读推荐 1. Alice's Adventures in Wonderland 爱丽丝漫游奇境记 音频与文本下载地址:链接:http: ...
- HTML 文本内容居中
简单描述:使用bootstrap 的model弹出框,里边的标题内容是靠左的,想把内容居中. 操作:给标题的class加上"text-center". 另外 我发现,在使用mode ...
- Python-数据类型之元组
一:元组 元组是一个只读列表,可以使用count,index等,但是元组里的元素不能更改,也不能增加,删除 元祖的一级元素不可更改,当一级元素有可变数据类型时,如列表,列表中的元素可变 tup = ( ...
- 抓取某网站信息时遇到的问题及解决 The character set provided in ContentType is invalid. Cannot read content as string using an invalid character set
var response = httpClient.SendAsync(requestMessage).Result; content = response.Content.ReadAsStringA ...
- python中thread的setDaemon、join的用法的代码
下面内容是关于python中thread的setDaemon.join的用法的内容. #! /usr/bin/env python import threading import time class ...