diff --git a/Python/sum-of-subarray-minimums.py b/Python/sum-of-subarray-minimums.py new file mode 100644 index 000000000..17bbc0ed2 --- /dev/null +++ b/Python/sum-of-subarray-minimums.py @@ -0,0 +1,49 @@ +# Time: O(n) +# Space: O(n) + +# Given an array of integers A, find the sum of min(B), +# where B ranges over every (contiguous) subarray of A. +# +# Since the answer may be large, return the answer modulo 10^9 + 7. +# +# Example 1: +# +# Input: [3,1,2,4] +# Output: 17 +# Explanation: Subarrays are [3], [1], [2], [4], [3,1], +# [1,2], [2,4], [3,1,2], [1,2,4], [3,1,2,4]. +# Minimums are 3, 1, 2, 4, 1, 1, 2, 1, 1, 1. Sum is 17. +# +# Note: +# - 1 <= A.length <= 30000 +# - 1 <= A[i] <= 30000 + +import itertools + + +# Ascending stack solution +class Solution(object): + def sumSubarrayMins(self, A): + """ + :type A: List[int] + :rtype: int + """ + M = 10**9 + 7 + + left, s1 = [0]*len(A), [] + for i in xrange(len(A)): + count = 1 + while s1 and s1[-1][0] > A[i]: + count += s1.pop()[1] + left[i] = count + s1.append([A[i], count]) + + right, s2 = [0]*len(A), [] + for i in reversed(xrange(len(A))): + count = 1 + while s2 and s2[-1][0] >= A[i]: + count += s2.pop()[1] + right[i] = count + s2.append([A[i], count]) + + return sum(a*l*r for a, l, r in itertools.izip(A, left, right)) % M