LeetCode978. 最长湍流子数组

Posted youdias

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode978. 最长湍流子数组相关的知识,希望对你有一定的参考价值。

问题:978. 最长湍流子数组

当 A 的子数组 A[i], A[i+1], ..., A[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 的最大湍流子数组的长度。

 

示例 1:

输入:[9,4,2,10,7,8,8,1,9]
输出:5
解释:(A[1] > A[2] < A[3] > A[4] < A[5])

示例 2:

输入:[4,8,12,16]
输出:2

示例 3:

输入:[100]
输出:1

 

提示:

  1. 1 <= A.length <= 40000
  2. 0 <= A[i] <= 10^9
 

链接:https://leetcode-cn.com/contest/weekly-contest-120/problems/longest-turbulent-subarray/

分析:

所谓湍流子数组,其实就是要增加减少交替,可以预处理下,得到数据走势,1表示增加,-1表示减少,0表示相等,然后找到最大的交替变换长度即可。

一段结束的条件是:

1.数据走势变平

2.连续增加或者连续减少。

遇到的坑有:

数据一直符合到最后一个数据,结果没能拿到最新的数据,需要在循环结束时候更新结果,或者循环内判断满足结束条件了即对结果进行更新。

 

AC Code:

 

class Solution {
public:
    int maxTurbulenceSize(vector<int>& A) {
        int ret = 1;
        if (A.size() == 1)
        {
            return 1;
        }
        vector<int> mark;
        int tmp = A[0];
        for (int i = 1; i < A.size(); i++)
        {
            if (A[i] > tmp)
            {
                mark.emplace_back(1);
            }
            else if (A[i] < tmp)
            {
                mark.emplace_back(-1);
            }
            else
            {
                mark.emplace_back(0);
            }
            tmp = A[i];
        }

        // 0 1 -1
        int tmplength = 1;
        int pre =mark[0];
        for (int i = 1; i < mark.size(); i++)
        {        
            if (mark[i] == 0)
            {
                //遇到平移,结束,并且看情况取下一个值
                ret = max(tmplength, ret);
                tmplength = 1;        
                if (i + 1 < mark.size())
                {
                    pre = mark[i+1];
                }
                else
                {
                    break;
                }
            }
            else
            {
                if (pre * mark[i] == 1)
                {
                    //同向,结束
                    ret = max(ret, tmplength);                    
                    tmplength = 1;
                    pre = mark[i];
                }
                else
                {
                    pre = mark[i];
                    tmplength++;
                }
            }
            
        }
    ret = max(tmplength, ret);  //提交错了一次,就是在这里,数据一直符合要求, 结果就少对答案进行更新一次。
        return ret+1;
    }
};

 

其他:

第一code:

typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------


class Solution {
public:
    int maxTurbulenceSize(vector<int>& A) {
        int cur=0,ma=0,i;
        FOR(i,A.size()-1) {
            if(i%2==0) {
                if(A[i]<A[i+1]) cur++;
                else cur=0;
                
            }
            else {
                if(A[i]>A[i+1]) cur++;
                else cur=0;
            }
            ma=max(ma,cur);
        }
        cur=0;
        FOR(i,A.size()-1) {
            if(i%2==1) {
                if(A[i]<A[i+1]) cur++;
                else cur=0;
                
            }
            else {
                if(A[i]>A[i+1]) cur++;
                else cur=0;
            }
            ma=max(ma,cur);
        }
        return ma+1;
        
    }
};

两次循环,一次看先增后减的最大长度,一次看先减后增的最大长度。

 

另一个code:

class Solution {
public:
    int maxTurbulenceSize(vector<int>& A) {
        int cnt=0;
        bool fl=false;
        int ans=0;
        for(int i=1;i<A.size();i++){
            if(i&&A[i]==A[i-1]){
                cnt=0;
                continue;
            }
            bool nex=(A[i]<A[i-1]);
            if(cnt==0){
                fl=nex;
                cnt=1;
            }
            else{
                if(fl!=nex){
                    fl=nex;
                    cnt++;
                }
                else{  
                    fl=nex;
                    cnt=1;
                }
            }
            ans=max(ans,cnt);
        }
        return ans+1;
    }
};

 

以上是关于LeetCode978. 最长湍流子数组的主要内容,如果未能解决你的问题,请参考以下文章

❤️思维导图整理大厂面试高频数组16: 最长湍流子数组的动态规划构建 和 滑动窗口解法, 力扣978❤️

《LeetCode之每日一题》:88.最长湍流子数组

力扣LeetCode-300. 最长递增子序列-题解

力扣LeetCode-300. 最长递增子序列-题解

Leetcode 300. 最长递增子序列

leetcode-最长无重复子数组-79