求大值:栈顶到栈底(小到大)
求小值:栈顶到栈顶(大到小)
栈中仅记录下标即可,用下标寻找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]))
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 i1:
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