栈、队列(更新至9.14)

今天不知道为什么 好困
什么时候要用到栈呢,真的搞不太清楚,先上题

6.30 求最大矩形面积

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。
在这里插入图片描述
先给出简单解法:
依次遍历每一个矩阵宽度,找到这个宽度的边界。
比如:
对于height[0] = 2,我们找到它的边界是左0右0,面积是1;
对于height[2] = 5,我们找到它的边界是左2右3,面积是2。

但时间复杂度是 O ( n 2 ) O(n^2) O(n2)

其实我们思考一下,找边界的问题,就是找到左/右边第一个没它高的height,然后停止!这类“在一维数组中找第一个满足某种条件的数”的场景就是典型的单调栈应用场景。

我们希望只经过一次遍历就找到每一个height的左右边界,OK,那么元素从左到右依次进栈。
如何找左边界?——元素height进栈前,把栈内大于height的元素依次弹出,现在的栈顶元素的index就是第一个比它小的。(+1就是左边界)
如何找右边界?——元素height出栈的时候,当前遍历的index就是第一个比它小的(-1就是右边界)(因为当前的h[index] < height才导致出栈 )
有一种特殊情况,可能有的元素不会出栈,如[1,2,3,4,5],这个时候我们初始右边界为n - 1

一定要好好细品!

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        n, stack = len(heights), []
        left, right = [0] * n, [n - 1] * n
        area = 0
        for i in range(n):
            while (stack and heights[i] <= heights[stack[-1]]):
                index = stack[-1]
                stack.pop()
                right[index] = i - 1
            left[i] = stack[-1] + 1 if stack else 0
            stack.append(i)
        area = max((right[i] - left[i] + 1) * heights[i] for i in range(n)) if n > 0 else 0
        return area

附上代码,这个代码栈存的是index而不是height,因为height更容易访问。

百度笔试第三题 走矩阵

给定一个字符矩阵,矩阵仅由’r’,‘e’,'d’组成。

求从左上角到右下角的最少步数。可以从上下左右四个方向走,但是不能从’r’->‘d’, ‘e’->‘r’,‘d’->‘e’。

第一行输入n m (1<n,m<500)

n表示矩阵的行 m表示矩阵的列

接下来n行 输入一个长为m的”red”字符串

“red”字符串是指所有字符均为”r"或”e"或”d”

你可以在矩阵中上下左右移动

但是r不能移动到d e不能移动到r d不能移动到e

输出从左上角走到右下角最少需要多长时间

如无法到达输出-1

其实这种走迷宫的题很多,我之前用的都是回溯或者dp,但这题不太能用这两个方法,因为:
①回溯的是时间复杂度太高了
②dp一般设置为只能往右或往下。这种题的路径可能会绕过来(因为有的路径是不通的!)
所以题解用到了队列,这样的好处就是能够任意行动,而且每个格子只记录第一次到的时间(初始的时间设置为一个大数)

from collections import deque

ban = "rderde"
mp = {}
for i in range(0, 5, 2):
    mp[ban[i + 1]] = ban[i]
n, m = map(int, input().split())
board = []
for _ in range(n):
    s = list(input().strip())
    board.append(s)

inf = 10 ** 9

q = deque([(n - 1, m - 1)])
g = [[inf] * m for _ in range(n)]
g[n - 1][m - 1] = 0
while q:
    x, y = q.popleft()
    for dx, dy in [(0, -1), (0, 1), (1, 0), (-1, 0)]:
        nx, ny = dx + x, dy + y
        if (
            0 <= nx < n
            and 0 <= ny < m
            and mp[board[x][y]] != board[nx][ny]
            and g[nx][ny] == inf
        ):
            g[nx][ny] = g[x][y] + 1
            q.append((nx, ny))

if g[0][0] == inf:
    print(-1)
else:
    print(g[0][0])

这里从终点走到了起点(不知道为什么这么设计…)
用了一个字典来告诉我们x禁止走向y
注意还有一个for dx,dy in[(),(),(),()]:
这个用法挺常见的,记录一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值