居然可以用暴力解法过,但是面试的时候肯定要被问follow-up。先写暴力的,再写一个改进的。
class Solution:
def subArrayRanges(self, nums: List[int]) -> int:
lenth = len(nums)
res = 0
for include in range(lenth):
maxn = float('-inf')
minn = float('inf')
for add in range(include, lenth):
maxn = max(maxn, nums[add])
minn = min(minn, nums[add])
res += (maxn-minn)
return res
改进版本的:
class Solution:
def subArrayRanges(self, nums: List[int]) -> int:
A1 = [float('-inf')] + nums +[float('-inf')]
A2 = [float('inf')] + nums + [float('inf')]
stack1 = []
def findmin(A1, stack1):
res = 0
for idx, num in enumerate(A1):
while stack1 and A1[stack1[-1]] > num:
curmin_pos = stack1.pop()
leftend = stack1[-1] if stack1 else -1
res += A1[curmin_pos] * (idx - curmin_pos)*(curmin_pos - leftend)
stack1.append(idx)
return res
minadd = findmin(A1, stack1)
stack2 = []
def findmax(A2, stack2):
res = 0
for idx, num in enumerate(A2):
while stack2 and A2[stack2[-1]] < num:
curmax_pos = stack2.pop()
leftend = stack2[-1] if stack2 else -1
res += A2[curmax_pos] * (idx - curmax_pos)*(curmax_pos - leftend)
stack2.append(idx)
return res
maxadd = findmax(A2, stack2)
return maxadd - minadd
题目特别像是907,只是这题也注意,907最小值是1,两头补0就可以,但是本题有负数,处理最小值时两头补float(‘-inf’),处理最大值时,两头补正的float(‘inf’)
class Solution:
def sumSubarrayMins(self, A: List[int]) -> int:
A = [0] + A + [0]
monostack = []
res = 0
for idx, num in enumerate(A):
while monostack and A[monostack[-1]] > num:
curmin_pos = monostack.pop()
leftend = monostack[-1]
res += A[curmin_pos] * (curmin_pos - leftend) *(idx - curmin_pos)
monostack.append(idx)
return res%(10**9+7)