Leetcode 山字形序列_正反掃描

一隻老風鈴發表於2020-09-25

合唱團問題:給定一組身高不同的人,刪除其中幾個人,使得剩下的人組成先升高後減少的合唱團佇列

思路:正、反掃描

  • left[i]表示正向第i個人為末尾的最長遞增子序列
  • right[i]表示反向第i個人為末尾的最長遞增子序列

計算left[i]+right[i]-1便可找到最大的合唱團佇列長度

 

 

題目描述

雲霄飛車在上坡下坡的過程是非常刺激的。如果把整個雲霄飛車的軌道當作是一個長度為n的陣列num,那麼在雲霄飛車上坡時陣列中的值是呈現遞增趨勢的,到了最高點以後,陣列中的值呈現遞減的趨勢,把符合這樣先增後減規律的陣列定義為金字塔陣列,請你幫牛牛在整個num陣列中找出長度最長的金字塔陣列,如果金字塔陣列不存在,請輸出0。

示例1

輸入

複製

4,[1,2,3,1]

輸出

複製

4

 

 

 

【思路】和合唱團類似,採取正、反向掃描

  • left[i]表示從i位置向左組多可以連續遞減多少次
  • right[i]表示從i位置向右最多可以連續遞減多少次

 

以left[]迭代計算為例:

  • 若num[i]>num[i-1]  則left[i]=left[i-1]
  • 否則,left[i]=0

峰頂法

最後,遍歷那些山峰(left[i]>0 && right[i]>0)的left[i]+right[i]+1  找到其中的最大值

整個時間複雜度為線性級別: O(N)

 

 int getMaxLength(int n, vector<int>& num) {
        // write code here
        if(n==1)
            return 1;
       vector<int> left(n,0);//left[i]=k表示i位置向左可以下降多少元素
       vector<int> right(n,0);//right[i]=k表示i位置向右可以下降多少元素
        for(int i=1;i<n;i++)
            if(num[i]>num[i-1])
                left[i]=left[i-1]+1;
        for(int i=n-2;i>=0;i--)
            if(num[i]>num[i+1])
                right[i]=right[i+1]+1;
        int ans=0;
        for(int i=0;i<n;i++)
        {
            if(left[i]>0 && right[i]>0)
                ans=max(ans,left[i]+right[i]+1);
        }
        
        return ans;
    }

 

 

另一種思路:峰谷法

尋找到那些峰谷(區域性最低點   num[i]<num[i-1] && num[i]<num[i+1])

兩兩峰谷之間的距離,即為中間波峰的長度

 

相關文章