题解 | #数据分析#

数据分析

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
全部评论

相关推荐

点赞 评论 收藏
转发
点赞 评论 收藏
转发
点赞 1 评论
分享
牛客网
牛客企业服务