我们有一组N个正元素。我们可以在这个数组上执行M操作。在每个操作中,我们必须选择长度为W的子阵列(连续)并将每个元素增加1.阵列的每个元素最多可以增加K倍。 我们必须执行这些操作,以使数组中的最小元素最大化。
1 <= N,W <= 10 ^ 5
1 <= M,K <= 10 ^ 5
时间限制:1秒
我可以想到一个O(n ^ 2)解决方案,但它超出了时间限制。有人可以为此提供O(nlogn)或更好的解决方案吗?
P.S.-这是一个面试问题
答案 0 :(得分:0)
如果我们将数组的副本按升序排序,将每个元素指向其原始索引,该怎么办?在增加元素时考虑优先级顺序。此外,最终的运营顺序是否重要?
一旦最低元素到达下一个最低元素,那么必须增加什么?如果我们对任何一个元素应用k
操作,那么应用w
这些增量是否重要?
答案 1 :(得分:0)
它在Google采访中被问到,我通过在范围逻辑中使用滑动窗口,堆和增量来解决。我将分三部分解决问题:
找出大小为W的每个子数组中的最小值。这可以通过使用带有优先级队列的滑动窗口在 O(n)中完成。每个窗口的最大值必须插入具有3个变量的 min-heap :[array_value,left_index,right_index]
现在,将辅助数组初始化为大小为N的0。对堆执行 M 次弹出操作,并在每次弹出操作中执行3个任务:
值,left_index,right_index = heap.pop()#最小弹出的理论函数
将值增加1, 在left_index的辅助数组中增加1,在in中减少1 right_index + 1处的辅助数组
再次将此对插入堆中。 [具有递增的值和相同的索引]
执行M次操作后,将遍历给定数组与辅助数组,并将累加总和添加到数组中索引“ i”处元素的索引“ 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()
# sliding window + heap building
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])
# auxiliary array
temp = [0 for i in range(n)]
# performing M increment operations
while m:
top = heappop(heap)
temp[top[1]] += 1
try:
temp[top[2] + 1] -= 1
except:
# when the index is last, so just ignore
pass
top[0] += 1
heappush(heap, top)
m -= 1
# finding cumulative sum
sumi = 0
for i in range(n):
sumi += temp[i]
arr[i] += sumi
print(min(arr))
if __name__ == '__main__':
# find([1, 2, 3, 4, 5, 6], 6, 5, 2)
# find([73, 77, 60, 100, 94, 24, 31], 7, 9, 1)
# find([24, 41, 100, 70, 97, 89, 38, 68, 41, 93], 10, 6, 5)
# find([88, 36, 72, 72, 37, 76, 83, 18, 76, 54], 10, 4, 3)
find_maximised_minimum([98, 97, 23, 13, 27, 100, 75, 42], 8, 5, 1)