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

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

最直接的方法就是针对当前位置往前搜索比较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))

你可能感兴趣的:(这是基础,leetcode,最大值,历史最大数,最近最大数,python)