84.柱状图中最大的矩形
此题乍一看很难,但有思路还是能写出来的
与接雨水相似,但此题要找的是第一个较小的,这样我们就可以确定当前高度能形成的矩形的最大值。
for i in range(n - 2, -1, -1):
while tmp1 and heights[i] <= heights[tmp1[-1]]:
tmp1.pop()
if tmp1:
h1.append(tmp1[-1])
else:
h1.append(-1)
tmp1.append(i)
这个维护栈的代码都是一个模子刻出来的,下面处理结果的方式才是精髓
for i in range(n):
x = 0
if h1[i] != -1: //存在较小值,说明此方向的矩形最大值就到较小值下表为止,进行记录
x += (h1[i] - i - 1) * heights[i]
else: //不存在较小值,说明该方向都可以有这个高度,进行记录
x += (n - i - 1) * heights[i]
if h2[i] != -1:
x += (i - h2[i] - 1) * heights[i]
else:
x += i * heights[i]
mx = max(x + heights[i], mx) //加上本身一格的高度,找到最大值即可
好久没有一次写出困难题,果然有思路与没思路是完全不一样的
总结
本次是我二刷随想录,更多的是对同一道题有了新的感悟,对同一个方法有了新的认识,对忘记的方法又重新加深了印象。
仍然需要加深练习的:
1.二分查找(多种形式的运用,以及在一些困难题会与其他方法一起运用,达到更低的复杂度)
2.快慢指针(常用于一些环形以及定位问题)
3.双指针(经常用于有序情况,三数之和作为例题理解非常合适)
4.KMP算法(字符串匹配使用,匹配到最近位置以减少查找时间)
5.二叉树的前中后序遍历,不同的遍历可以解决不同的问题
6.回溯模板(两种,一种确认,一种添加数组)
7.贪心(更多是对题的理解,看似简单比较难想)
8.dp(类型多样,总结起来就是全局规划,一个从0到n的过程,还要注意dp数组的建立,压缩状态很关键)
9.单调栈(找第一个较大或较小,要注意的是如何利用单调栈,其他都很简单)
学到了什么:
1.写博客,加深了我对题目的理解,以往写对就是写对,但现在写对还得说得出来对在哪,什么方法对,是实实在在的有在思考,而不是巧合。
2.组成体系,解法不是偶然明白,也不是灵光乍现,就像一棵树一样,一层一层的走下去就能到相应的结点,建立好自己的算法体系,遇到题才能表现得游刃有余。
3.方法运用,方法有了,解题没有头绪肯定是角度不对,从多个角度想问题,想动态规划,我们可以从状态、初始化、遍历顺序、遍历公式四个方向去思考问题,多想多得。
4.愿意讨论,遇到多方法的题,多去看不同方法,不是一定要说找出最好的方法,更多的是去了解每个方法能解题的角度,与志同道友探讨每个方法的利用,能更好的加深对方法的理解。
last but not the least:
路还得继续向前走,训练营结束但代码路还远未结束,仅以此纪念这个做了点事的寒假。