题目描述:
题解:
方法一:暴力解
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