K题题解:bfs+单调队列

第一眼:bfs傻X题,然后发现它能跳。
然后嘴巴BB了一句,起点bfs,终点bfs,单调栈+单调栈合并的傻X题。

(...几小时后...)

MD这个题怎么这么麻烦。

好吧,这个题确实是没什么可以说的地方,没思路的话可能是不知道“单调队列处理固定划窗极值”这个套路。

单调队列处理固定划窗极值

它是这么个套路啊,说现在有一个长度大小为n的数组,数组中有一些整数,请你求出所有长度大小为k的子区间的极值。
还是给个例子比较好说明,假设n=9,k=3,a[]={5,6,7,8,9,4,1,1,1}
跟着划窗取子区间,取到的第一个子区间是{5,6,7}这个子区间,该子区间的最大值为7。
那么想一个问题,5和6两个数字有没有可能在划窗向右滑动的过程中作为一个最大值?
你发现是不可能的,因为5和6比7要小,并且他们的物理位置在7的左侧,划窗向右滑动的过程中5和6比7更早的被弹出这个划窗区间。
那既然没必要保留,那我存都不带存的,也就是对于{5,6,7}这个子区间有用的信息只有7。
那么在向右滑动1步之后7,8之间也是由于相同的原因,7再也不可能在8之后成为任何一个子区间的极值。
那么一直向右滑动划窗,直到{8,9,4}这段区间。虽然9是当前划窗内的极值,但是4这个备胎是有可能上位的。因为它寿命比9要长,等9被弹出划窗的时候它还在里面,所以4是要被保留的。

那么总结一下就是维护一个数据结构,每当输入的数据比tail位置的数字大时,就弹出最末尾的数字,反之只要单调递减就压进去。
所以维护一个“单调递减队列”就能够维护固定长度的划窗最大值问题。

跟这个题有什么关系呢,使用单调队列的话可以很轻松的扩展到k维空间。
对于这个题,其实就是起点bfs,终点bfs,然后找一个矩形区域内的最小值。
首先先把矩阵一行一行的切开,也就是把它变成“n个长度为m的一维数组”
然后就求出了“所有长度是定长的线段的极值”。
然后在对列在做一次,这次的权值改为刚刚每行线段求出的极值,再来一遍。
就变成了二维固定形状的矩阵的极值。

这种方法的复杂度仅为O(|高维空间容量|),而且实现起来也比ST表要简单,内存使用也比ST表更优。

全部评论

相关推荐

2024-12-29 11:08
湖南工业大学 Java
程序员牛肉:简历没什么大问题了。 而且不要再换项目了。三月份就开暑期实习了,现在都一月份了。实在来不及重新开一下项目了。把一个项目写完或许很快,但是把一个项目搞懂吃透并不简单。所以不要换项目了,把你简历上面的两个项目好好挖一挖吧。 具体 体现在:你能不能流利的说出你的项目的每一个功能点代码实现?你能不能说出在这块除了A技术之外,还有其他技术能够实现嘛?如果有其他技术能够实现,那你这块为什么选择了你当前用的这个技术?
投递牛客等公司
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务