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;
    }
};

原文地址:https://www.cnblogs.com/youdias/p/10294454.html

时间: 2024-11-06 13:19:52

LeetCode978. 最长湍流子数组的相关文章

js输出二维数组最长的子数组

var a=[[5,6,7],[15,16,8,7],[3,23,44,55,66]]; var max=a[0].length; for (var i = 1; i < a.length; i++) { if (max<a[i].length) { max=a[i].length; var b=i; } } alert(b); alert(a[b]);

使用后缀数组寻找最长公共子字符串JavaScript版

后缀数组很久很久以前就出现了,具体的概念读者自行搜索,小菜仅略知一二,不便讨论. 本文通过寻找两个字符串的最长公共子字符串,演示了后缀数组的经典应用. 首先需要说明,小菜实现的这个后缀数组算法,并非标准,只是借鉴了其中的思想. 小菜实现的算法,有两个版本,第一个是空间换时间,第二个是时间换空间. 空间换时间版本 1 /* 2 利用后缀数组获取两个字符串最长公共子字符串 3 空间换时间版本 4 @params 5 s1 String,要分析的字符串 6 s2 String,要分析的字符串 7 no

最长可整合子数组

可整合子数组:按由小到大排完序之后,后面的数比前一个数大1,如:[2,4,3,6,5]就是可整合数组. 1 // getLiL.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <hash_set> 7 #include <iterator> 8 #include <set> 9 10 using namespace std

[LeetCode] Shortest Unsorted Continuous Subarray 最短无序连续子数组

Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too. You need to find the shortest such subarray and output its length. E

(算法)和为0的最大连续子数组

题目: 和为零的最大连续子数组 思路: 我首先想到的是前缀数组和,遍历一遍数组,计算出sum[i](表示从0-i的子数组之和). 有了前缀数组和,只要sum[i]=sum[j](i<j),那么区间[i+1,j]就是和为零的子数组,只要在遍历前缀数组和时记录最长的区间即可. 需要注意的是:当sum[i]等于0时,其区间为[0,i]. 在判断sum[i]=sum[j](i<j)时,有个查找的过程,要么直接遍历j左边的所有数(增加时间复杂度),要么通过map来存储对应和的下标位置(空间换时间).(详

hihocoder-1796-完美K倍子数组

hihocoder-1796-完美K倍子数组  #1796 : 完美K倍子数组 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 如果一个数组满足长度至少是2,并且其中任意两个不同的元素Ai和Aj (i ≠ j)其和Ai+Aj都是K的倍数,我们就称该数组是 完美K倍数组. 现在给定一个包含N个整数的数组A = [A1, A2, ... AN]以及一个整数K,请你找出A的最长的完美子数组B,输出B的长度. 如果这样的子数组不存在,输出-1. 输入 第一行包含两个整数N和

动态规划--之--最长公共子字符串

package 动态规划;import java.util.Scanner;public class LogestCommonZiXuLie { public static void main(String[] args)     {      Scanner scan = new Scanner(System.in);      while(scan.hasNextLine())        {          String str = scan.nextLine();         

找出一个整数数组的和最大的连续子数组

题目: 给任意一个整数数组,找出这个数组的和最大的连续子数组(子数组的和最大且子数组连续).要求:算法的时间复杂度为O(n). 程序设计思想: 1:用maxValue记录当前连续子数组和为最大的和的值,初始化其值为:maxValue=a[0].注:记数组为a[n]. 2:这个过程总的思想就是,从数组头开始往后,每次加进一个值,它们的和记为tempValue,若tempValue比新加进来的数值本身要小,应该从这个位置开始重新开始计算tempValue的值.而每次的tempValue都应该和max

求一个数组中和最小的连续子数组

#include<stdio.h> #define MAX_LENGTH 10 int main() { int a[MAX_LENGTH]={1,2,3,-2,4,-6,-8,5,3,1}; int i,j,beg,end,tmp,min=0x7fffffff; //beg和end分别为子数组中首末元素下标,min为无穷大的数 beg=end=tmp=0; for(i=0;i<MAX_LENGTH;++i) { tmp=a[i]; for(j=i+1;j<MAX_LENGTH;+