📌  相关文章
📜  阵列中相隔至少 K 距离的对的最大总和(1)

📅  最后修改于: 2023-12-03 15:42:23.608000             🧑  作者: Mango

阵列中相隔至少 K 距离的对的最大总和

给定一个整数数组和一个正整数K,找到该数组中的两个数字,它们之间的距离至少为K,并且它们的和最大。如果不存在这样的两个数字,则返回0。

解法

一种解法是使用滑动窗口,通过维护一个长度为K的窗口,来寻找满足条件的数字对。

具体的,我们从左到右遍历数组,对于每个位置i,我们记录从i开始到i+K-1范围内的最大值的下标j。这里使用一个单调递减的双端队列,从左到右依次存储[j-K+1,j-K+2,...,j]中的下标,队列中的下标对应的值是单调递减的。新加入的下标i先和队尾下标比较大小,如果更小,则将队尾下标弹出,因为他们不再可能是最大值的下标。然后,我们比较队头下标j和i的距离是否大于等于K,如果不是,则继续遍历下一个位置,否则,将数组中i和j对应的值相加即为当前的最大值,并尝试更新答案。然后将i加入队列。

具体实现见下面的代码片段。

代码
def max_sum_with_gap(arr, K):
    n = len(arr)
    queue = collections.deque()
    ans = 0
    for i in range(n):
        while queue and i - queue[0] >= K: # 如果队头下标与i的距离超过K,弹出
            queue.popleft()
        if queue: # 队列非空,队头是从i-K到i-1范围内的最大值
            ans = max(ans, arr[i] + arr[queue[0]])
        while queue and arr[queue[-1]] <= arr[i]: # 比新加入的下标i小的下标都可以不用了
            queue.pop()
        queue.append(i)
    return ans

时间复杂度为O(n),空间复杂度为O(K)。