这是谷歌面试中的一个问题,我使用滑动窗口、堆和区间增量来解决它。我将分为三个部分来解决这个问题:
找出大小为W的每个子数组的最小值。可以使用带有优先队列的滑动窗口在O(n)时间内完成。每个窗口的最大值必须插入到一个min-heap中,具有3个变量: [array_value, left_index, right_index]
现在,创建一个初始化为0且大小为N的辅助数组。在堆上执行M次弹出操作,在每个弹出操作中执行3个任务:
value, left_index, right_index = heap.pop() # 理论上弹出最小值的函数
将值加1,
在左索引处的辅助数组中增加1,在右索引+1处的辅助数组中减少1
再次将此对插入堆中。[带有增加的值和相同的索引]
执行M次操作后,使用辅助数组遍历给定的数组,并将累计总和添加到索引'i'处的元素。
返回数组的最小值。
时间复杂度
O(N) <- 每个窗口的最小元素和建立堆。
O(M*logN) <- 提取和插入到堆中。
O(N) <- 遍历以添加累积和。
因此,总体时间复杂度为O(N + M*logN + N),即O(M*logN)
空间复杂度
O(N) <- 额外的数组和堆。
可以轻松优化一些以上内容,例如仅插入堆中的值,仅插入left_index,而right_index = left_index + k。
我的代码
from heapq import heappop, heappush
from collections import deque
def find_maximised_minimum(arr, n, m, k):
"""
arr -> Array, n-> Size of array
m -> increment operation that can be performed
k -> window size
"""
heap = []
q = deque()
for i in range(k):
while q and arr[q[-1]] > arr[i]:
q.pop()
q.append(i)
for i in range(k, n):
heappush(heap, [arr[q[0]], i - k, i - 1])
while q and q[0] <= i - k:
q.popleft()
while q and arr[q[-1]] > arr[i]:
q.pop()
q.append(i)
heappush(heap, [arr[q[0]], n - k, n - 1])
temp = [0 for i in range(n)]
while m:
top = heappop(heap)
temp[top[1]] += 1
try:
temp[top[2] + 1] -= 1
except:
pass
top[0] += 1
heappush(heap, top)
m -= 1
sumi = 0
for i in range(n):
sumi += temp[i]
arr[i] += sumi
print(min(arr))
if __name__ == '__main__':
find_maximised_minimum([98, 97, 23, 13, 27, 100, 75, 42], 8, 5, 1)
O(n^2)
解决方案是什么?请在此发布,无论您认为它有多么琐碎。 - meowgoesthedog