leetcode1438. 绝对差不超过限制的最长连续子数组

题目描述:

题解:

方法一:暴力解

maxlen记录满足条件的子串最大长度,从数组中第一个元素开始向后寻找字串,若满足要求,更新maxlen

def longestSubarray(self,nums, limit):
    maxlen = float("-inf")
    numslen = len(nums)
    for i in range(numslen):
        for j in range(i+1,numslen+1):
            subnums = nums[i:j]
            submax = max(subnums)
            submin = min(subnums)
            gap = submax-submin
            if gap<=limit:
                if (j-i)>maxlen:
                    maxlen=(j-i)
    return maxlen

题目中的3个测试样例均通过,但提交超时

方法二:滑动窗口

<1>left right记录窗口左右端位置,初始left=0  right=1,字串subnums=nums[left:right]

<2>遍历nums数组,若将nums[i]加入subnums,subnums仍满足限制,则right+1 ,更新maxlen, 否则left+1 right+1窗口右移

def longestSubarray(self, nums, limit):
    left = 0
    right = 1
    subnums = nums[left:right]
    lennums = len(nums)
    if lennums == 1:
        return 1
    maxlen = float("-inf")
    for i in range(1,lennums):
        submax = max(subnums)
        submin = min(subnums)
        submax = max(submax,nums[i])
        submin = min(submin,nums[i])
        gap = submax-submin
        if limit>=gap:
            right = i+1
            if right-left>maxlen:
                maxlen=right-left
        else:
            left=left+1
            right = right+1
        subnums = nums[left:right]
    return maxlen

提交仍然超时:

方法三:滑动窗口+有序集合

参考:https://zhuanlan.zhihu.com/p/351892676

利用第三方的平衡树库,例如 Python 中的 sortedcontainers

<1>left right ret分别记录窗口左右端编号,子数组长度,初始均为0,定义SortedList s

<2>遍历数组,将nums[right]加入s,计算s中最大最小值之差,若不满足limit,left右移知道满足条件,利用right-left+1更新ret

from sortedcontainers import *

class Solution:

    def longestSubarray(self, nums, limit):

        s = SortedList()

        n = len(nums)

        left = right = ret = 0

        while right < n:

            s.add(nums[right])

            while s[-1] - s[0] > limit:

                s.remove(nums[left])

                left += 1

            ret = max(ret, right - left + 1)

            right += 1

        return ret

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值