首页 > 其他分享 >八. 栈和单调栈

八. 栈和单调栈

时间:2022-12-07 15:07:09浏览次数:51  
标签:return int self pop 单调 stack def


普通栈:

​剑指 Offer 09. 用两个栈实现队列​

class CQueue:
def __init__(self):
self.A, self.B = [], []

def appendTail(self, value: int) -> None:
self.A.append(value)

# 栈底元素(对应队首元素)无法直接删除,需要将上方所有元素出栈再删除。
def deleteHead(self) -> int:
if self.B: return self.B.pop()
if not self.A: return -1
while self.A:
self.B.append(self.A.pop())
return self.B.pop()


# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()

​面试题 03.04. 化栈为队​

class MyQueue:

def __init__(self):
"""
Initialize your data structure here.
"""
self.stack1 = []
self.stack2 = []

def push(self, x: int) -> None:
"""
Push element x to the back of queue.
"""
self.stack1.append(x)


def pop(self) -> int:
"""
Removes the element from in front of queue and returns that element.
"""
if len(self.stack2) == 0:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()



def peek(self) -> int:
"""
Get the front element.
"""
if len(self.stack2) == 0:
while self.stack1:
self.stack2.append(self.stack1.pop())
return self.stack2[-1]


def empty(self) -> bool:
"""
Returns whether the queue is empty.
"""
return len(self.stack2) == 0 and len(self.stack1) == 0


# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()

​225. 用队列实现栈​

​面试题 03.01. 三合一​

class MyStack:

def __init__(self):
"""
Initialize your data structure here.
"""
self.q = []

def push(self, x: int) -> None:
"""
Push element x onto stack.
"""
self.q.append(x)
q_length = len(self.q)
while q_length > 1:
self.q.append(self.q.pop(0)) #反转前n-1个元素,栈顶元素始终保留在队首
q_length -= 1

def pop(self) -> int:
"""
Removes the element on top of the stack and returns that element.
"""
return self.q.pop(0)

def top(self) -> int:
"""
Get the top element.
"""
return self.q[0]


def empty(self) -> bool:
"""
Returns whether the stack is empty.
"""
return not bool(self.q)





# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()

​20. 有效的括号​

class Solution:
def isValid(self, s: str) -> bool:
if len(s) % 2 == 1: return False
pairs = {'(':')','[':']','{':'}'}
stack = list()
# stack中存左括号。 如果是左括号, 加入栈中; 如果是右括号, 判断栈顶元素的键的值是否等于当前元素
for c in s:
if c in pairs:
stack.append(c)
elif not stack or pairs[stack.pop()] != c:
return False
return not stack

​32. 最长有效括号​

class Solution:
def longestValidParentheses(self, s: str) -> int:
if not s: return 0
res = 0
# stack一边匹配消消乐, 一边入栈
# 这一步可以防止stack中匹配完为空时pop()报错
stack = [-1]
for i in range(len(s)):
if s[i] == "(":
stack.append(i)
else:
# 如果是右括号则出栈
stack.pop()
# 如果栈是空的话, 把右括号放进来
if not stack: stack.append(i)
# 当前全部数减去剩余无法配对的数(单身)即res
else: res = max(res, i - stack[-1])
return res

​22. 括号生成​

​剑指 Offer II 085. 生成匹配的括号​

​面试题 08.09. 括号​

class Solution:
@lru_cache(None)
def generateParenthesis(self, n: int) -> List[str]:
if n == 0:
return ['']
ans = []
for c in range(n):
for left in self.generateParenthesis(c):
for right in self.generateParenthesis(n-1-c):
ans.append('({}){}'.format(left, right))
return ans

​394. 字符串解码​

class Solution:
def decodeString(self, s: str) -> str:
stack, res, multi = [], "", 0
for c in s:
if c == '[':
stack.append([multi, res])
res, multi = "", 0
elif c == ']':
cur_multi, cur_res = stack.pop()
res = cur_res + cur_multi * res
elif '0' <= c <= '9':
multi = multi * 10 + int(c)
else:
res += c
return res
'''
if 数字, then 将数字转换为整数,用于后续倍数计算
if 字符, 延长当前字符串
if 左括号,当前状态压入栈
if 右括号,弹出状态,组合字符串
'''

​150. 逆波兰表达式求值​

class Solution:
def evalRPN(self, tokens: List[str]) -> int:
dict = {
"+": add,
"-": sub,
"*": mul,
"/": lambda x, y: int(x / y), # 需要注意 python 中负数除法的表现与题目不一致
}

stack = list()
for token in tokens:
try:
num = int(token)
except ValueError:
num2 = stack.pop()
num1 = stack.pop()
num = dict[token](num1, num2)
finally:
stack.append(num)

return stack[0]

​剑指 Offer 31. 栈的压入、弹出序列​

class Solution:
def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
i = j = 0
stack = []
for i in range(len(pushed)):
stack.append(pushed[i])
while stack and stack[-1] == popped[j]:
stack.pop()
j += 1
return not stack

​剑指 Offer II 025. 链表中的两数相加​

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
stack1, stack2 = deque([]), deque([])
while l1:
stack1.append(l1.val)
l1 = l1.next
while l2:
stack2.append(l2.val)
l2 = l2.next

carry, p = 0, None
while stack1 or stack2 or carry:
num1 = stack1.pop() if stack1 else 0
num2 = stack2.pop() if stack2 else 0
ans = num1 + num2 + carry
carry = ans // 10
ans %= 10
# 递归思想
p = ListNode(ans, p)
return p

单调栈:

​面试题 03.05. 栈排序​

# Python3 辅助栈模拟
class SortedStack:

def __init__(self):
self.stack = list()


def push(self, val: int) -> None:
t = list()
while self.stack and self.stack[-1] < val:
t.append(self.stack.pop())
self.stack.append(val)
while t:
self.stack.append(t.pop())


def pop(self) -> None:
if not self.isEmpty():
self.stack.pop()


def peek(self) -> int:
if self.isEmpty():
return -1
return self.stack[-1]


def isEmpty(self) -> bool:
return len(self.stack) == 0



# Python3 堆模拟
# Your SortedStack object will be instantiated and called as such:
# obj = SortedStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.peek()
# param_4 = obj.isEmpty()

import heapq
class SortedStack:

def __init__(self):
self.stack = list()
heapq.heapify(self.stack)


def push(self, val: int) -> None:
heapq.heappush(self.stack,val)


def pop(self) -> None:
if not self.isEmpty():
ref = heapq.heappop(self.stack)
return ref

def peek(self) -> int:
if self.isEmpty():
return -1
ref = heapq.heappop(self.stack)
heapq.heappush(self.stack,ref)
return ref


def isEmpty(self) -> bool:

return len(self.stack) == 0





# Your SortedStack object will be instantiated and called as such:
# obj = SortedStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.peek()
# param_4 = obj.isEmpty()

​155. 最小栈​

​面试题 03.02. 栈的最小值​

​剑指 Offer 30. 包含min函数的栈​

class MinStack:
def __init__(self):
self.stack = []
self.min_stack = [math.inf]

def push(self, x: int) -> None:
self.stack.append(x)
self.min_stack.append(min(x, self.min_stack[-1]))

def pop(self) -> None:
self.stack.pop()
self.min_stack.pop()

def top(self) -> int:
return self.stack[-1]

def getMin(self) -> int:
return self.min_stack[-1]

# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

​739. 每日温度​

​剑指 Offer II 038. 每日温度​

class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
stack, ans = [], [0] * len(temperatures)
# 1.若栈为空或当日温度小于栈顶温度,则直接入栈
# 2.若当日温度大于栈顶温度,说明栈顶元素升温日找到,将栈顶元素出栈,计算其与当日相差的天数
for day, tmp in enumerate(temperatures):
while stack and tmp > stack[-1][0]:
stack_tmp, stack_day = stack.pop()
ans[stack_day] = day - stack_day
stack.append((tmp, day))
return ans

​84. 柱状图中最大的矩形​

​剑指 Offer II 039. 直方图最大矩形面积​

class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
stack = [-1]
heights.append(0)
n, ans = len(heights), 0
for i in range(n):
# 单调递增栈
while stack and heights[i] < heights[stack[-1]]:
p = stack.pop()
l, r = stack[-1], i
# 计算以栈顶元素勾勒出的最大面积
ans = max(ans, heights[p] * (r - l - 1))
stack.append(i)
return ans

​85. 最大矩形​

​剑指 Offer II 040. 矩阵中最大的矩形​

​面试题 17.24. 最大子矩阵​

class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
res_nums = [0]*len(matrix[0])
max_s = 0
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if int(matrix[i][j]) == 0:
res_nums[j] = 0
res_nums[j] += int(matrix[i][j])
max_s = max(max_s, self.get_max_s(res_nums) ) # 求出当前形成柱形的面积,与之前比较取最大的面积
return max_s

def get_max_s(self, nums: list[int]): # 求柱形最大的面积,利用上题思路
nums.append(-1)
stack_index = []
res = 0
for i in range(len(nums)):
while stack_index != [] and nums[i] < nums[stack_index[-1]]:
h_index = stack_index.pop()
left = -1 if stack_index == [] else stack_index[-1]
res = max(res, (i - left -1)*nums[h_index])
stack_index.append(i)
return res

标签:return,int,self,pop,单调,stack,def
From: https://blog.51cto.com/u_15905340/5919329

相关文章

  • 5.3.1 (2) 函数的单调性(含参函数)
    \({\color{Red}{欢迎到学科网下载资料学习}}\)[【基础过关系列】高二数学同步精品讲义与分层练习(人教A版2019)](https://www.zxxk.com/docpack/2875423.html)\({\col......
  • 5.3.1 (1) 函数的单调性
    \({\color{Red}{欢迎到学科网下载资料学习}}\)[【基础过关系列】高二数学同步精品讲义与分层练习(人教A版2019)](https://www.zxxk.com/docpack/2875423.html)\({\col......
  • leetcode 1687. 从仓库到码头运输箱子 动态规划 + 单调队列
    你有一辆货运卡车,你需要用这一辆车把一些箱子从仓库运送到码头。这辆卡车每次运输有 箱子数目的限制 和总重量的限制 。给你一个箱子数组 boxes 和三个整数portsCo......
  • 单调栈
    单调栈单调栈简单来说是在栈的先进后出基础之上额外添加一个特性:从栈顶到栈底的元素是严格递增(or递减)具体进栈过程如下:对于单调递增栈,若当前进栈元素为e,从栈顶开始遍历......
  • 单调队列学习笔记
    用处:滑动窗口维护区间最值核心思想:双端队列,队首放最大值/最小值的下标,1.清除不是更优的(队尾弹出)。2.清除过期的(队首弹出)。例题:https://www.luogu.com.cn/problem/P3088......
  • 算法刷题入门线性表|单调栈
     一、概念1、栈的定义栈 是仅限在 一端 进行 插入 和 删除 的 线性表。 栈 又被称为后进先出(LastInFirstOut)的线性表,简称LIFO。2、栈顶栈 是一......
  • 单调栈
    给定一个长度为n 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1。#include<iostream>#include<stack>usingnamespacestd;intn;stack<int>......
  • 《浅谈决策单调性动态规划的线性解法》阅读随笔
    读下来唯二的感想这就是集训队吗真nb这就是集训队吗写的什么jb这latex就很离谱好吧一个变量改好几次名字我都不知道他在干什么啊对了没实现代码啊都是找的st......
  • 单调栈和单调队列
    P5788【模板】单调栈入栈时候判定,如果不符合栈内的规则,则让栈顶的元素出栈。voidsolve(){stack<int>sc;ufr(i,1,n){if(sc.empty()){sc.emp......
  • 决策单调性优化dp二则
    CielandGondolas  CodeForces-321E题意:有n个人,第i个人和第j个人放在一起时会产生a[i][j]的沮丧值(是社恐吗),保证a[i][j]=a[j][i],两个人只产生一份沮丧值。将n个人分成......