Home > OS >  given an array, find an algorithm that finds the sum of the maximums of consecutive subarrays times
given an array, find an algorithm that finds the sum of the maximums of consecutive subarrays times

Time:04-05

given an array I should compute the following sum in linear time:

my most naive implementation is O(N^2):

sum_ = 0

for i in range(n):
    for j in range(n, i, -1):
        sum_  = max(arr[i:j]) * (j-i)

I have no idea what to do? I have tried many algorithms but they were at best O(N*log(N)), but I should solve it in linear time, also, I don't get the idea, is there a mathematical way of just looking at an array and telling the result of the above sum?

CodePudding user response:

Keep a stack of (indices of) non-increasing values. So before appending the new value, pop smaller ones. Whenever you pop one, add its contribution to the total.

def solution(arr):
    arr.append(float('inf'))
    I = [-1]
    total = 0
    for i in range(len(arr)):
        while arr[i] > arr[I[-1]]:
            j = I.pop()
            a = j - I[-1]
            b = i - j
            total  = (a b)*a*b//2 * arr[j]
        I.append(i)
    arr.pop()
    return total

Correctness test with random lists of 500 values (Try it online!):

import random

def reference(arr):
    n = len(arr)
    return sum(max(arr[L : R 1]) * (R - (L-1))
               for L in range(n)
               for R in range(L, n))

for _ in range(5):
    arr = random.choices(range(10000), k=500)
    expect = reference(arr)
    result = solution(arr)
    print(result == expect, result)

Sample output (results for five lists, True means it's correct):

True 207276773131
True 208127393653
True 208653950227
True 208073567605
True 206924015682
  • Related