Longest Mountain in Array 数组中的最长山脉

我们把数组 A 中符合下列属性的任意连续子数组 B 称为 “山脉”

  • B.length >= 3
  • 存在 0 < i < B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]

(注意:B 可以是 A 的任意子数组,包括整个数组 A。)

给出一个整数数组 A,返回最长 “山脉” 的长度。

如果不含有 “山脉” 则返回 0

示例 1:

输入:[2,1,4,7,3,2,5]
输出:5
解释:最长的 “山脉” 是 [1,4,7,3,2],长度为 5。

示例 2:

输入:[2,2,2]
输出:0
解释:不含 “山脉”。

提示:

  1. 0 <= A.length <= 10000
  2. 0 <= A[i] <= 10000

思路一:山脉的定义是必须有上坡和下坡才算山脉,如果只有上坡或者只有下坡都不算山脉,所以这道题可以类似之前的两遍扫描法,先倒着扫描一遍,找出每个点作为下坡顶点的最长距离down[i],再顺着扫描一遍,找出每个点作为顶点的上坡距离up[i]。然后判断如果对于当前顶点i,上坡距离up[i]和下坡距离down[i]均不为零,那么i可以作为一个山头,计算山坡长up[i]+down[i]+1,然后在所有坡长中取一个最长的坡长。

参考代码:

class Solution {
public:
    int longestMountain(vector<int>& A) {
	vector<int> up(A.size(), 0);
	vector<int> down(A.size(), 0);
	int res = 0;
	for (int i = A.size() - 2; i >= 0; i--) if (A[i] > A[i + 1]) down[i] = down[i + 1] + 1;
	for (int i = 1; i < A.size(); i++) {
		if (A[i] > A[i - 1]) up[i] = up[i - 1] + 1;
		if(up[i] && down[i]) res = max(res, up[i] + down[i] + 1);
	}
	return res;
    }
};

思路二:由于只能扫描一次,所以要判断出哪些点不能作为山头,而且要能区别不同的山头(包括上坡段和下坡段),我们从头扫描数组,记录两个变量up和down,记录到当前下标i时,上坡和下坡有多长。up和down在以下两个条件成立时会被归为0。

A[i - 1] == A[i] or ( down > 0 && A[i - 1] < A[i] )

条件的意思是如果前后两个值相等A[i - 1] == A[i],那么不管是上坡还是下坡截止到当前第i个元素得到的up和down都是无效的,所以必须归为0。如果当前正在下坡路段down>0但是突然有个元素不满足下坡时后一个元素小于前一个元素的特性(A[i - 1] < A[i] ),那么就证明第i个元素已经是坡底元素的下一个元素了,不属于这个山头,所以up和down要归零。

参考代码:

class Solution {
public:
    int longestMountain(vector<int>& A) {
	int up = 0, down = 0;
	int res = 0;
	for (int i = 1; i < A.size(); i++) {
		if (down > 0 && A[i] > A[i - 1] || A[i] == A[i - 1]) up = down = 0;
		up += A[i] > A[i - 1];
		down += A[i] < A[i - 1];
		if(up && down) res=max(res,up+down+1);
	}
	return res;
    }
};

 

猜你喜欢

转载自blog.csdn.net/qq_26410101/article/details/81176116