单调栈结构(求数组中每一个数最近的大值or小值)

求大值:栈顶到栈底(小到大)
求小值:栈顶到栈顶(大到小)
栈中仅记录下标即可,用下标寻找arr中的值
不满足弹出,结算弹出的数据
**应用1:**求小值:栈顶到栈顶(大到小)
在这里插入图片描述

def maxsquare(arr): #单调栈,从上到下,从大到小,找两边离自己最近的比自己小的值
    stack=[]        #单调栈,谁让他弹出谁是离它最近的小的,下面的是另一边比自己小的
    maxarea=0 #结果
    for i in range(len(arr)):
        while stack and arr[i]<=arr[stack[-1]]: #当前值小于栈顶,弹出并结算
            j=stack.pop()
            if not stack:
                k=-1     #左边界
            else:
                k=stack[-1]
            curarea=(i-k-1)*arr[j]
            maxarea=max(maxarea,curarea)
        stack.append(i)
    while stack:   #检查栈中剩余元素
        j=stack.pop()
        if not stack:
            k=-1
        else:
            k=stack[-1]
        curarea=(len(arr)-k-1)*arr[j]
        maxarea = max(maxarea, curarea)
    return maxarea
    print(maxsquare([4,3,2,5,6]))

**应用2:**求小值:栈顶到栈顶(大到小)
在这里插入图片描述

def maxsquare(arr): #单调栈,从上到下,从大到小,找两边离自己最近的比自己小的值
    stack=[]        #单调栈,谁让他弹出谁是离它最近的小的,下面的是另一边比自己小的
    maxarea=0 #结果
    for i in range(len(arr)):
        while stack and arr[i]<=arr[stack[-1]]: #当前值小于栈顶,弹出并结算
            j=stack.pop()
            if not stack:
                k=-1     #左边界
            else:
                k=stack[-1]
            curarea=(arr[j])*(i-k-1)
            maxarea = max(maxarea,curarea)
        stack.append(i)

    while stack:   #检查栈中剩余元素
        j=stack.pop()
        if not stack:
            k=-1
        else:
            k=stack[-1]
        curarea=(len(arr)-k-1)*arr[j]
        maxarea = max(maxarea, curarea)
    return maxarea

def maxRectangle(matrix):
    maxareal=0
    helpp=[0 for i in range(len(matrix[0]))]
    for i in range(len(matrix)):
        for j in range(len(matrix[0])):
            if matrix[i][j]==0:
                helpp[j]=0
            else:
                helpp[j]+=1
        maxareal=max(maxareal,maxsquare(helpp))
    return  maxareal

mat=[[1,0,1,1],[1,1,1,1],[1,1,1,0]]
print(maxRectangle(mat))

应用3:
小的找大的,找最近的比自己高的山峰
(1)无重复:
(n-2)2+1=2n-3
在这里插入图片描述
(2)有重复
在这里插入图片描述
在这里插入图片描述

# 山峰问题,可互相看见的山峰对
# 找到全局最大值,单调栈,(栈顶到栈底,小到大)
# 栈中数据:(高度,个数)
# 从最大值的下一个位置遍历,小的找大的,找最近的大值
class pair():    #栈中元素
    def __init__(self,value):
        self.value=value
        self.times=1
def nextindex(size,i):#循环数组i的下一个位置
    if i<size-1:
        return i+1
    else:
        return 0
def getsum(n):     #C(k,2)
    if n>1:
        return n*(n-1)/2
    else:
        return 0
def getmaxnumber(arr):
    maxindex=0
    for i in range(len(arr)):  #找到最大值的位置
        if arr[i]>arr[maxindex]:
            maxindex=i
    value=arr[maxindex]   #记录最大值
    stack = []
    stack.append(pair(value))   # (值,出现次数)先把最大值扔进去
    indexx=nextindex(len(arr),maxindex)  #最大值的下一个位置
    res=0

    while indexx!=maxindex:  #遍历整个数组
        value=arr[indexx]
        while stack and value>stack[-1].value:   #满足弹出条件
            times=stack.pop().times
            res+=getsum(times)+times*2
        if stack and stack[-1].value==value:   #值相等时
            stack[-1].times+=1                        #压到一起
        else:                                                  #小于栈顶元素或弹出完之后小于栈顶元素
            stack.append(pair(value))
        indexx=nextindex(len(arr),indexx)

    while stack:                                #结算栈中剩余元素(三种情况)
        times=stack.pop().times
        res+=getsum(times)
        if stack:
            res+=times
            if len(stack)>1:
                res+=times
            else:
                if stack[-1].times>1:
                    res+=times
    return  res

猜你喜欢

转载自blog.csdn.net/weixin_40876685/article/details/89021097
今日推荐