leetcode978 Longest Turbulent Subarray

A subarray A[i], A[i+1], …, A[j] of A is said to be turbulent if and only if:

For i <= k < j, A[k] > A[k+1] when k is odd, and A[k] < A[k+1] when k is even;
OR, for i <= k < j, A[k] > A[k+1] when k is even, and A[k] < A[k+1] when k is odd.

That is, the subarray is turbulent if the comparison sign flips between each adjacent pair of elements in the subarray.

Return the length of a maximum size turbulent subarray of A.

Note:
1.1 <= A.length <= 40000
2.0 <= A[i] <= 10^9

Example 1:

Input: [9,4,2,10,7,8,8,1,9]
Output: 5
Explanation: (A[1] > A[2] < A[3] > A[4] < A[5])

Example 2:

Input: [4,8,12,16]
Output: 2

Example 3:

Input: [100]
Output: 1

给定一个数组,求这个数组中的最长子集的个数。要求这个子集中相邻的元素之间的大小关系不同,反应在平面坐标系中为波浪形。
若相邻元素间大小关系不同,记数组 diff[i] = A[i] - A[i+1]。那么对于满足要求的子集的diff数组应为 正负交替负正交替两种情况。
则原问题转化为求 diff数组 中最长的 正负交替 的子集
(负正交替与此问题相类似)
接下来,考虑如何判断是 正负交替 出现的。首先设置变量 flag 初始值为 true ,表示当前位置上应当是 + 。当该位置上元素的正负 与 flag 所代表的相一致,那么 flag 取反,进入下一位的判断;若不一致,表示当前这一可能为最长的正负交替的子集结束,进入判断处理。
在判断处理中,更新记录的最长长度。若当前位置上应当为 + ( flag = true )但实际为 -( ele < 0),则 flag 初始化为 true,进入下一位判断;若当前位置上应为 - ( flag = false )但实际上为 + ( ele > 0 ),则 flag 初始化为 true,从当前位置开始判断。
Ps:遍历数组过程中,不一定进入判断处理中,如整个数组处于正负交替的模式下,即时遍历结束,仍未进入判断处理。因此,要在结束循环时,强制更新记录的最长长度
Ps:注意题目定义的子集长度的计算方式


class Solution {
private:
    vector<int> diff;
public:
    int maxTurbulenceSize(vector<int>& A) {
        int ans=INT_MIN;
        int temp=0;
        int len=A.size();
        
        for(register int i=0;i<len-1;i++)
            diff.push_back(A[i]-A[i+1]);
        
        bool flag=true;
        int pos=0;
        int difLen=diff.size();
        while(pos<difLen){
            int ele=diff[pos];
            if(flag){       //postive position
                if(ele > 0){        //actual postive 
                    temp++;
                    flag= !flag;
                }else{              //actual negative 
                    ans=max(ans,temp);
                    temp=0;
                    flag=true;
                }
                pos++;
            }else{         //negative position
                if(ele < 0){        //actual negative 
                    temp++;
                    flag= !flag;
                    pos++;
                }else{              //actual postive 
                    ans=max(ans,temp);
                    temp=0;
                    flag=true;
                }
            }
        }
        ans=max(ans,temp);
        
        flag=false;
        pos=0;
        temp=0;
        while(pos<difLen){
            int ele=diff[pos];
            if(flag){       //postive position
                if(ele > 0){        //act p
                    temp++;
                    flag= !flag;
                    pos++;
                }else{              //act n
                    ans=max(ans,temp);
                    temp=0;
                    flag=false;
                }
            }else{         //negetive position
                if(ele < 0){        //act n
                    temp++;
                    flag= !flag;
                }else{              //act p
                    ans=max(ans,temp);
                    temp=0;
                    flag=false;
                }
                pos++;
            }
        }
        ans=max(ans,temp);
        
        ans++;
        return ans;
    }
};

除了上述判断方法之外,还可以判断任意三个元素之间的大小关系,来确定是否符合要求
对于A数组中任意三个连续的元素有
在这里插入图片描述
其中符合要求的只有
在这里插入图片描述
上述两种情况。
所以,可以判断连续三个元素的大小关系,来确定最长的正负交替子集的长度。
根据diff数组的定义,判断连续三个元素的大小,只需得知在diff数组中连续两个元素的正负。若为正,表示连接两点的线段斜向上;若为负,表示连接两点的线段斜向下;若为零,表示连接两点的线段水平。而在这里的判断依据为相邻的任意两元素正负不同。
在这里对长度的记录不同于上一种方法,由于时三个一组的判断,因此在初始状态下,长度记录 temp 值应为 1 ,才能符合后续操作(判断成立,长度加一)。
而由于长度记录的初始值为 1 ,对于

[1,1,1,1,1,1,1]

这样的数据在执行时就会出现错误,因为这组数据不存在符合要求的子集,而经过上述程序后,子集的长度至少是2。
所以,对于这种数组内元素全部相同的情况,需要进行特判。
Ps:当给定的数组长度为1时,不执行对最长长度记录的更新,因此即时遍历结束时,ans 的值仍为 0 ,所输出的结果正确。


class Solution {
private:
    vector<int> diff;
public:
    int maxTurbulenceSize(vector<int>& A) {
        int len=A.size();
        bool sepc=false;
        for(register int i=0;i<len-1;i++)
            if(A[i]!=A[i+1]){
                sepc=true;
                break;
            }
        if(!sepc)
            return 1;
        int ans=0;
        int temp=1;
        for(register int i=0;i<len-1;i++)
            diff.push_back(A[i]-A[i+1]);
        int difLen=diff.size();
        
        for(register int i=0;i<difLen;i++){
            if(cmp(i)){
                temp++;
            }else{
                
                ans=max(ans,temp);
                temp=1;
            }
        }
        ans++;
        
        return ans;
    }
    bool cmp(int pos){
        int len=diff.size();
        
        if(pos+1<len){
            if( (diff[pos]<0 && diff[pos+1]<0) || (diff[pos]>0 && diff[pos+1]>0) || diff[pos+1]==0 || diff[pos]==0)
                return false;
            else
                return true;
        }else{
            return false;
        }
    }
};

猜你喜欢

转载自blog.csdn.net/white_156/article/details/86617564