力扣 leetcode 978. 最长湍流子数组 (python)双指针 + 直接遍历

Topic

当 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 的最大湍流子数组的长度。

Example_1

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

Example_2

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

Example_3

输入:[100]
输出:1

Tips

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

Solution_1

Tips中说明长度不会小于1

先判断是否满足条件
设置一个新的列表data用于记录递增和递减

将递增的情况前一位设置为1
将递减的情况前一位设置为-1

这里需要对仅有一位或者无递增递减情况的先判断
属于这两种情况的直接返回1

之后利用双指针进行判断
设置左指针left和右指针right

先设置一个左指针的位置0为开始
同时判断右指针结束的位置

之前设置递增为1,递减为-1
如果满足题目中递增和递减交换的条件
那么相邻的两个值相乘为-1

利用这个规律进行判断右指针结束位置
如果右指针与它data中下一位的值相乘为-1
说明满足条件(右指针位置还可右移)
右移右指针直到不满足条件或者右指针到达边界(右指针为倒数第二位)

由于题目中是寻求连续的序列且为最大值
那么我们左指针的位置从右指针结束的位置开始判断
运行效率会更高

因为如果左指针仅右移一位
那么判断的还是原来的连续序列
且判断出来的序列长会比之前更小
所以左指针的位置需要挪动到右指针结束的位置

最后每次连续序列结束判断当前序列的长度
若比之前记录的最大长度大
则赋值给max_len

(不建议用max函数判断,原因点此处)

Code_1

class Solution:
    def maxTurbulenceSize(self, arr: List[int]) -> int:
        n = len(arr)
        data = [0] * (n - 1)

        for i in range(n - 1):
            if arr[i] > arr[i + 1]: 
                data[i] = 1
            if arr[i] < arr[i + 1]: 
                data[i] = -1

        if data == [0] * (n - 1):
            return 1
        left = 0
        right = 0
        max_len = 0

        while left < n - 1:
            while right < n - 2:
                if data[right] * data[right + 1] < 0:
                    right += 1
                else:
                    break
            if right - left + 1 > max_len:
                max_len = right - left + 1

            right += 1
            left = right
            
        return max_len + 1

Result_1

力扣 leetcode 978. 最长湍流子数组 (python)双指针 + 直接遍历_第1张图片

Solution_2

Tips中说明长度不会小于1

第二种方法则仅需判断一次

先判断特殊情况

长度为1的直接返回1
长度为2的只要不相等则都满足条件
相等的返回1
不相等的返回2

之后则需要每三位进行一次判断
三位数字满足题目条件的有两种情况

一种是递减 + 递增
一种是递增 + 递减

满足这两情况中的任何一种都可以满足题目中的条件

但是在这里需要先对开头两位进行判断:

相等的令最大长度和当前长度均为1
不相等的令最大长度和当前长度均为2

然后则按三位的情况判断即可
若遇到不满足的按如下判断即可

相等的令当前长度均为1
不相等的令当前长度均为2

最后每次连续序列结束判断当前序列的长度
若比之前记录的最大长度大
则将临时长度length赋值给max_len

(不建议用max函数判断,原因点此处)

Code_2

class Solution:
    def maxTurbulenceSize(self, arr: List[int]) -> int:
        n = len(arr)
        
        if  n == 1: 
            return n
        if n == 2:
            if arr[0] == arr[1]:
                return 1
            else:
                return 2
        
        if arr[0] == arr[1]:
            max_len = length = 1 
        else:
            max_len = length = 2

        for i in range(2,n):
            if arr[i - 2] < arr[i - 1] > arr[i] or arr[i - 2] > arr[i - 1] < arr[i]:
                length += 1
                if length > max_len:
                    max_len = length
            else:
                if arr[i - 1] == arr[i]:
                    length = 1
                else:
                    length = 2

        return max_len

Result_2

力扣 leetcode 978. 最长湍流子数组 (python)双指针 + 直接遍历_第2张图片

你可能感兴趣的:(python,leetcode,leetcode,算法,数据结构,python,双指针)