1. 题目
2. 解答
2.1 方法一
left 数组表示当前元素左边比当前元素小的元素个数,right 数组数组表示当前元素右边比当前元素小的元素个数。在山脉的中间 B[i] 处,其左边和右边肯定都有小于 B[i] 的元素,而山脉的长度即为 left[i] + right[i] + 1。
class Solution {
public:
int longestMountain(vector<int>& A) {
int n = A.size();
if (n < 3) return 0;
vector<int> left(n, 0);
vector<int> right(n, 0);
for (int i = 1; i < n; i++)
{
if (A[i] > A[i-1]) left[i] = left[i-1] + 1;
}
for (int i = n-2; i >= 0; i--)
{
if (A[i] > A[i+1]) right[i] = right[i+1] + 1;;
}
int len = 0;
for (int i = 0; i < n; i++)
{
if (left[i] != 0 && right[i] != 0)
len = max(len, left[i] + right[i] + 1);
}
return len;
}
};
2.2 方法二
max_than_left 数组若为 1 则表明当前元素比左边元素大,max_than_right 数组若为 1 则表明当前元素比右边元素大。
若为山脉则两个数组应该为如下序列
数组取值 | |||||
---|---|---|---|---|---|
max_than_left | 1(可选) | ... | 1(必选) | ... | 0(可选) |
max_than_right | 0(可选) | ... | 1(必选) | ... | 1(可选) |
class Solution {
public:
int longestMountain(vector<int>& A) {
int n = A.size();
if (n < 3) return 0;
vector<int> max_than_left(n, 0);
vector<int> max_than_right(n, 0);
for (int i = 1; i < n; i++)
{
if (A[i] > A[i-1]) max_than_left[i] = 1;
}
for (int i = 0; i < n-1; i++)
{
if (A[i] > A[i+1]) max_than_right[i] = 1;
}
int result = 0;
int len = 0;
int left_flag = 0;
int middle_flag = 0;
int right_flag = 0;
for (int i = 0; i < n; i++)
{
if (max_than_left[i] == 1 && max_than_right[i] == 0)
{
if (left_flag) result++;
else
{
result = 3;
left_flag = 1;
}
}
else if (max_than_left[i] == 1 && max_than_right[i] == 1)
{
if (left_flag)
{
result++;
}
else
{
result = 3;
}
left_flag = 0;
middle_flag = 1;
}
else if (max_than_left[i] == 0 && max_than_right[i] == 1)
{
if (right_flag) result++;
if (middle_flag)
{
middle_flag = 0;
right_flag = 1;
result++;
}
}
else
{
right_flag = 0;
middle_flag = 0;
left_flag = 0;
result = 0;
}
if (middle_flag || right_flag) len = max(len, result);
}
return len;
}
};
获取更多精彩,请关注「seniusen」!