2021/02/08 每日一题 最长湍流子数组

LeetCode上最长湍流子数组,中等难度,最近做题好难的感觉,QAQ

湍流子数组的含义是在一个数组内,比较符号在相邻数字之间反复变化,那么这个数组就是湍流数组
例如[10,7,8]就是一个湍流数组,因为10 > 7 < 8

那么假设给了一个数组[9,4,2,10,7,8,8,1,9],可以通过滑动块的方式来解题,设定以下变量
pre : 保存之前的增减关系
current: 保存当前的增减关系
res: 保存当前最大湍流子数组的长度
首先一开始设left = 0;right = 1


会比较初始的递增递减趋势,这里直接用arr[right] - arr[right - 1]的得到的数来存储,如果为正数,那么就是递增,如果为负数那么就是递减,如果为0,那么就表示是两个相同的数,以上完成窗口的初始化,之后开始窗口的扩展,此时res = 1


right++窗口扩展,此时left = 0;right = 2,之前通过计算arr[right] - arr[right - 1]可得pre = -5是递减的


比较arr[right] - arr[right - 1],此时得到的数为-2,和pre相比,两者都是小于0的数,那么这个[0,2]区间不满足湍流数组的关系,那么此时left要移动到right后一位,让left = right - 1

为什么是right-1位?
因为如果在这个区间内有一个不满足这个关系的,在这个区域内的所有数都不会满足,就会要直接跳过整个区域


例如[9,4,5,2,7,8][7,8]的关系不满足湍流关系,那么去看[4,5,2,7,8][5,2,7,8][2,7,8]这几个left向右移动一位的情况得到的数组就都不会满足,所以要让left直接到right后面 一位,取[7.8]这个区间,重新开始计算湍流数组

之后不断判断数组,可以得到这样的窗口


这个时候pre = 5current = -1res =5,right继续增加的话
会出现arr[right] - arr[right - 1] = 0的情况,这个时候也是不满足湍流关系的,那么left是需要进行移动的,这里需要移动到right的位置

为什么是right的位置
因为如果是移动到right-1的位置,那么会出现下面这个情况


那么这个移动后的结果是直接不满足条件的,所以会移动到right所在的位置

之后继续移动的话也只会得到这样的窗口,这样获得的窗口是3,那么和之前5相比,还是5最大



所以返回的结果是5

var maxTurbulenceSize = function(arr) {
  // 记录窗口左右
  let left = 0
  let right = 1
  // 如果出现[1]/[]的情况,就返回数组长度
  if (arr.length < 2) return arr.length
  // 记录上一次的增减结果
  let pre = arr[1] - arr[0]
  // 记录当前的增减结果
  let current = 0
  // 记录返回的结果
  let res = 0
  // 移动的范围是到数组末尾截止,因为这里right初始为1,所以不用设置为arr.length - 1的情况
  while(right < arr.length) {
    // 首先记录当前right当前的增减结果
    current = arr[right] - arr[right - 1]
    // 当right===1的情况,就把这个值赋值给pre
    // 如果current和pre的正负关系相同,就判断为不满足关系
    if(current > 0 && pre > 0 || current < 0 && pre < 0) {
      // 这种情况就是让left到right-1位
      left = right - 1
    }
    // 如果出现current = 0的情况,那么就是arr[right] = arr[right - 1],也是不满足湍流关系
    if(current === 0) {
      // 这种情况要让left到right的位置
      left = right
    }
    // 不是上面两个情况,就表示遵守湍流关系,窗口扩展
    right++
    // 比较之前存的结果,和当前窗口大小
    res = Math.max(res,right - left)
    // 将当前结果给pre
    pre = current
  }
  return res
};

你可能感兴趣的:(2021/02/08 每日一题 最长湍流子数组)