求历史数据中最近的K个数的最大值

本文介绍了一种在O(N)时间复杂度内求解滑动窗口最大值的高效算法,通过维护历史最大与次大元素及其生命周期,实现对数组及流式数据的最大值快速查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于一个数组,求解位置iii之前的kkk个(包括当前位置)数中的最大数。

最直接的方法就是针对当前位置往前搜索比较k-1个数,得到最大的那个数。该方法的时间复杂度为O(N∗K)O(N*K)O(NK)。能否在O(N)O(N)O(N)的时间复杂度中求解呢?

当然是可以的,我们只需要记住历史K中的最大与第二大的数以及这两个数的生命周期,然后通过不停地前移,我们不停更新这个两个数就可。【这便是思路了】

特别的,针对已知的数组,我们可以通过记录历史的第一、第二大数的位置坐标,即可通过计算得到它们的生命周期以及值。

下面是代码:

def maxWindow(arr, k):
    from collections import deque
    queue = deque()
    i = 0
    result = [0] * len(arr)
    while i < len(arr):
        if len(queue) > 0 and i - queue[0] >= 3:
            queue.popleft()
        if len(queue) == 0:
            queue.append(i)
        elif len(queue) == 1:
            if arr[queue[-1]] <= arr[i]:
                queue.pop()
            queue.append(i)
        else:
            while len(queue) > 0 and arr[queue[-1]] <= arr[i]:
                queue.pop()
            queue.append(i)
        result[i] = arr[queue[0]]
        i += 1
    return result

那么,针对流式数据应该如何处理呢?同样采取以上方法即可。

显然,通过记录位置下标的方法不可用了。那么我们只有记录并更新历史k中最大两个数的生命周期了。

代码如下:

class MaxWindow:
    def __init__(self, k):
        self.k = k
        self.a, self.b = None, None
        self.a_life, self.b_life = 0, 0

    def max(self, num):
        if self.a_life >= self.k:
            self.a, self.b = self.b, None
            self.a_life, self.b_life = self.b_life, 0
        if self.a is None:
            self.a = num
            self.a_life += 1
        elif self.b is None:
            if self.a <= num:
                self.a = num
                self.a_life = 1
            else:
                self.b = num
                self.a_life += 1
                self.b_life = 1
        else:
            if self.a <= num:
                self.a, self.b = num, None
                self.a_life, self.b_life = 1, 0
            elif self.b <= num:
                self.b = num
                self.a_life += 1
                self.b_life = 1
            else:
                self.a_life += 1
                self.b_life += 1
        return self.a

t = MaxWindow(3)
for num in [1, 3, 2, 5, 4, 6, 7, 2, 1, 2, 3]:
    print(t.max(num))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值