最大值减去最小值小于或等于num的子数组数量 Python

给定数组arr和整数num,保证max(arr[i…j]) - min(arr[i…j]) <=num,其中max(arr[i…j])表示子数组 arr[i…j]中的最大值,min(arr[i…j])表示子数组arr[i…j]中的最小值。假定数组长为N,实现时间复杂度O(N)的解法。

0开头的有N个,1开头有N-1个,等差数列,一共有O(N 2 ^2 2)个子数组。
首先暴力方法 O(N 3 ^3 3)

def isValid(arr, start, end, num):
	max1=max(arr[start:end+1])
	min1=min(arr[start:end+1])
	return max1-min1 <= num

arr = [2,3,4,2,6,2,5,1]
n = len(arr)
num = 3
res1 = 0
for start in range(n):
	for end in range(start, n):
		if(isValid(arr, start, end, num)):
			res1 += 1
print(res1)

最优解 O(N)
一个子数组 如果[R, L]达标了,max-min<=m, 那么R…L内的子数组都达标,如果[R, L]不达标了max-min>m,那么…R, L…往外扩都不达标了。
一开始让L=0, R 往外扩,到最后一个达标的数位置X,再往下一个位置x+1就不达标了,这样就得到了 0,0-1,…0-x,共x+1个。这样位置0 开头的就判断完了。然后L来到1位置,接着看R能扩到哪个位置。直到L到最后的位置。
在扩的过程中判断子数组是否达标,用滑动窗口。

qmin = [] #窗口内的最小值
qmax = [] #窗口内的最大值
L = 0
R = 0
res2 = 0
while L<len(arr):
    while R<len(arr):
        while len(qmin)!=0 and arr[qmin[-1]] >= arr[R]: #更新最小值
            qmin.pop()
        qmin.append(R)
        while len(qmax)!=0 and arr[qmax[-1]] <= arr[R]: 	#更新最大值
            qmax.pop()
        qmax.append(R)
        if arr[qmax[0]] - arr[qmin[0]] > num: #如果不满足了,break,R为X+1了,满足的有R-L个
            break
        R += 1
    res2  += R-L
    if qmin[0] == L:   #L要向右移动了,L位置的值要pop掉
        qmin.pop(0)
    if qmax[0] == L:
        qmax.pop(0)
    L += 1
print(res2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值