题解 | #数据分析#

数据分析

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

相关推荐

程序员小白条:你是沟通了900个,不是投了900份简历,你能投900份,意味着对面都要回复你900次,你早就找到实习了,没亮点就是这样的,别局限地区,时间投的也要早,现在都要7月了
点赞 评论 收藏
分享
头顶尖尖的程序员:我是26届的不太懂,25届不应该是找的正式工作吗?为什么还在找实习?大四还实习的话是为了能转正的的岗位吗
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务