动态规划之最长波形子数组

动态规划之最长波形子数组

LeetCode978 Longest Turbulent Subarray

当A的子数组A[i:j]满足下列条件之一时,我们称其为波形子数组:

对于i<=k<j,当k为奇数时,A[k]>A[k+1],当k为偶数时,A[k]<A[K+1];

或者:对于i<=k<j,当k为偶数时,A[k]>A[k+1],当k为奇数时,A[k]<A[k+1]。

也就是说,如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是波形子数组。

返回A的最长波形子数组的长度

子数组的问题,或者子字符串的问题,最典型如最长公共子字符串、最长公共子数组与本例最长波形子数组,都可以用动态规划解。

先确定下主题:给定数组arr[],求最长波形子数组的长度,

//DP解最长波形子数组
#include <iostream>
int DPLongestWaveSubArr(int arr[],size_t len){
    int **dp = new int *[len]; //i
    for(int i=0;i<len;i++) dp[i]=new int [len]; //j
    for(int k=len;k>0;k--){
        for(int i=0,j=len-k;i<k,j<len;i++,j++){
            //或int j=len-k;
            if(k==len) dp[i][j]=1;
            else if(k==len-1) dp[i][j]=2;
            else{
                int nL(dp[i][j-1]),nLD(dp[i+1][j-1]),nD(dp[i+1][j]);
                //dp[i][j-1]
                //arr[i:j-1]连arr[j]
                if((arr[j-2]-arr[j-1])*(arr[j]-arr[j-1])>0) nL++;
                //dp[i+1][j-1] 连arr[j]
                if(k==len-2){ //此时i+1==j-1,恒能连arr[j]
                    nLD++;
                }else{ //此时i+1<j-1,需要波形条件判断
                    if((arr[j-2]-arr[j-1])*(arr[j]-arr[j-1])>0) nLD++;
                }
                //dp[i+1][j]
                //arr[i+1:j]连arri]
                if((arr[i+2]-arr[i+1])*(arr[i]-arr[i+1])>0) nD++;

                //取三个子数组连接(或不连接)至当前arr[i:j]的最长波形子数组长度
                dp[i][j]=std::max(std::max(nL,nLD),nD);
            }
        }
    }
    return dp[0][len-1];
}
int main(int argc,char* argv[]){
    int arr[]={1,3,2,5,4,7,6};
    int nLongestWaweSubarr = DPLongestWaveSubArr(arr,7);

}

猜你喜欢

转载自blog.csdn.net/HayPinF/article/details/108371780