看到这个题,很明显会想到是两个“最长上升子序列”从左到右,从右到左各一遍,然后拼在一起即可。
关于最长上升子序列,普通解法是![图片说明](https://www.nowcoder.com/equation?tex=n%5E%7B2%7D "图片标题") 的时间复杂度
代码如下:

class Solution {
public:
    /**
     * 返回最大山峰序列长度
     * @param numberList int整型vector 给定的序列
     * @return int整型
     */
    int dp1[10005],dp2[10005];
    int mountainSequence(vector<int>& numberList) {
        // write code here
        int max1=-1,max2=0;
        int n = numberList.size();
        for(int i=0;i<n;i++)
         {
              dp1[i]=1;
              for(int j=0;j<i;j++)
              {
                   if(numberList[j]<numberList[i]) dp1[i]=max(dp1[i],dp1[j]+1);
              }
         }
         for(int i=n-1;i>=0;i--)
         {
              dp2[i]=1;
              for(int j=n-1;j>i;j--)
              {
                   if(numberList[i]>numberList[j]) dp2[i]=max(dp2[i],dp2[j]+1);
              }
         }
         //for(int i=0;i<n;i++) printf("%d ",dp2[i]);printf("\n");
         for(int i=0;i<n;i++)
         {
              max1=max(max1,dp1[i]+dp2[i]-1);
         }
         return max1;
    }
};

对于最长上升子序列,我们知道,有![图片说明](https://www.nowcoder.com/equation?tex=n%5Ctimes%20log_%7Bn%7D "图片标题")
那种二分的做法看下面代码,基本就是继承经典的那种二分求LIS,遍历每个元素的时候,记录当前维护的序列的长度,也就是以这个元素为结尾的元素的长度。然后倒着求一遍。

class Solution {
public:
    /**
     * 返回最大山峰序列长度
     * @param numberList int整型vector 给定的序列
     * @return int整型
     */
    int d[1000];
    int d1[1000];
    int d2[1000];
    int mountainSequence(vector<int>& numberList) {
        // write code here
        int n = numberList.size();
        memset(d,0,sizeof(d));
        memset(d1,0,sizeof(d1));
        memset(d2,0,sizeof(d2));
        int sum=0;
        for (int i=0; i<n; i++)
        {
            if(numberList[i]>d[sum]) {
                 d[++sum]=numberList[i];
            }
            else
            {
                int k=lower_bound(d,d+sum,numberList[i])-d;
                d[k]=numberList[i];
            }
            d1[i]=sum;
        }
        sum=0;
        for (int i=n-1; i>=0; i--)
        {
            if(numberList[i]>d[sum]) {
                d[++sum]=numberList[i];
            }
            else
            {
                int k=lower_bound(d,d+sum,numberList[i])-d;
                d[k]=numberList[i];
            }
            d2[i]=sum;
        }
        int sum1=0;
        for (int i=0; i<n; i++)
        {
            sum1=max(sum1,d1[i]+d2[i]-1);
        }
        return sum1;
    }
};

时间复杂度一下就降低了
下面这样写会更好一些

class Solution {
public:
    /**
     * 返回最大山峰序列长度
     * @param numberList int整型vector 给定的序列
     * @return int整型
     */
    int mountainSequence(vector<int>& numberList) {
        // write code here
        int n = numberList.size(), ret = 1;
        vector<int>left(n), right(n), dpl, dpr;
        for (int i = 0; i < n; i++)
        {
            auto itl = lower_bound(dpl.begin(), dpl.end(), numberList[i]);
            auto itr = lower_bound(dpr.begin(), dpr.end(), numberList[n - 1 - i]);
            if (itl == dpl.end()) dpl.push_back(numberList[i]);
            else *itl = numberList[i];
            if (itr == dpr.end()) dpr.push_back(numberList[n - 1 - i]);
            else *itr = numberList[n - 1 - i];
            left[i] = dpl.size();
            right[n - 1 - i] = dpr.size();
        }
        for (int i = 0; i < n; i++)
            ret = max(ret, left[i] + right[i] - 1);
        return ret;
    }
};

由于这个题不想卡时间,所以前一种普通做法也能过的