题解 | #数据分析#
数据分析
http://www.nowcoder.com/questionTerminal/e3780de8d2294a098a5fd6aff5dabde3
由于我们只需要考虑每个长度为N的子数组的最大值,因此我们枚举每个元素,记录其可以为子数组最大值的覆盖区间长度,在该区间内该元素始终为最大值;同时我们可以知道,若存在一个长度为m的子数组最大值为k,显然可以找到任意一个长度小于等于m的子数组使其最大值为k;因此我们首先通过单调栈求出每个元素的覆盖区间,同时倒序遍历子数组长度,并将当前符合长度的区间存入小顶堆,依次记录答案即可.
时间复杂度:O(nlogn)
import heapq
import collections
class Solution:
def getMinimums(self , numbers ):
n = len(numbers)
left_,right_ = [1 for i in range(n)],[1 for i in range(n)]
stack = []
for i in range(len(numbers)):
if not stack:
stack.append([i,numbers[i]])
else:
if stack[-1][1] >= numbers[i]:
stack.append([i,numbers[i]])
else:
while stack and stack[-1][1] < numbers[i]:
right_[stack[-1][0]] += i - 1 - stack[-1][0]
stack.pop(-1)
stack.append([i,numbers[i]])
if stack:
for i in range(len(stack) - 1):
right_[stack[i][0]] += stack[-1][0] - stack[i][0]
stack.clear()
for i in range(len(numbers) - 1,-1,-1):
if not stack:
stack.append([i,numbers[i]])
else:
if stack[-1][1] >= numbers[i]:
stack.append([i,numbers[i]])
else:
while stack and stack[-1][1] < numbers[i]:
left_[stack[-1][0]] += stack[-1][0] - i - 1
stack.pop(-1)
stack.append([i,numbers[i]])
if stack:
for i in range(len(stack) - 1):
left_[stack[i][0]] += stack[i][0] - stack[-1][0]
cnt = collections.defaultdict(list)
for i in range(len(left_)):
cnt[left_[i] + right_[i] - 1].append(numbers[i])
v = []
for k in cnt:
for m in cnt[k]:
v.append([k,m])
v.sort(key = lambda x:-x[0])
l = 0
heap = []
ans = [0] * n
# 倒序遍历保证了任意时刻堆中区间均符合我们需要的子数组长度
for i in range(n,0,-1):
while l < len(v) and v[l][0] >= i:
heapq.heappush(heap, v[l][1])
l += 1
ans[i - 1] = heap[0]
return ans