一 队列
实现:循环数组,链表
应用:与BFS紧密相连
见图与搜索
二 栈(单向操作)
实现:普通数组,链表
应用:DFS
见图与搜索
155. Min Stack
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
- push(x) -- Push element x onto stack.
- pop() -- Removes the element on top of the stack.
- top() -- Get the top element.
- getMin() -- Retrieve the minimum element in the stack.
考点:如果Min恰好在top上,pop掉Min后如何得到第二个Min?之后Min恰好又在top上,就需要得到第三个Min?
自然需要额外的空间去记录这些信息。所以用一个二维元组去记录当前stack下最小的值。
class MinStack:
def __init__(self):
self.stack = []
def push(self, x):
if not self.stack:
self.stack.append((x, x))
else:
self.stack.append((x, min(x, self.stack[-1][-1])))
def pop(self):
self.stack.pop()
def top(self):
return self.stack[-1][0]
def getMin(self):
return self.stack[-1][1]
84. Largest Rectangle in Histogram
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
符合求最大,而且是序列不可改动,为什么不用DP?因为暴力解法就是O(n^2),DP无法进行优化
根据木桶原理,要去找到每个木桶最短的边,以圆柱高度5为例,需要找到左边第一个比5小的数,和右边第一个比5小的数。
边界处理,左右边界各加一个0作为第一个木桶和最后一个木桶的边。
问题就转化为寻找两边第一个更小值。
引入一个单调栈的概念(没见过记住就好了),定义每次push一个值x之前,pop出所有比x小(或者大)的值。
性质:栈内的值永远是单调递增或者递减的。
但这里利用的是其pop和push的过程,因为每次push x到栈中之后,栈中的上一个值就是左边第一个比x小的值。
而在push x之前,pop出的第一个数y,x就是y右边第一个比y小的数。
这样单调栈就可以在O(n)内可以得到每个值左右第一个比他的小的值。
关键:
每次pop出的数可以同时得到左右两边第一个比他小的数,所以每次pop就可以得到一个体积,通过比较求出全局最大。
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
heights = [0] + heights + [0]
mono_stack = []
res = 0
for i, val in enumerate(heights):
if not mono_stack:
mono_stack.append(i)
else:
while True:
large_index = mono_stack[-1]
if val >= heights[large_index]:
mono_stack.append(i)
break
else:
height_index = mono_stack.pop()
res = max(res,
(i - mono_stack[-1] - 1) * heights[height_index])
return res
85. Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.
Input: [ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ] Output: 6
Largest Rectangle in Histogram的变形,以每一行为底,得到每层的高度,然后传入到largestRectangleArea中得到每行的最大面积。
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
def largestRectangleArea(heights):
heights = [0] + heights + [0]
mono_stack = []
res = 0
for i, val in enumerate(heights):
if not mono_