单调栈——求区间最小数乘区间和的最大值(单调增)
思路:
计算目标:计算以不同数作为区间最小数时,对应最大区间的(区间和*最小数)的值(因为最小数是固定的,最后要求的结果一定属于最小数*最大区间之和,因此找最大区间即可)。
数组元素依次入栈,当当前元素小于栈顶时,可以对栈顶元素作为最小数的情况进行计算(因为此时栈顶元素>其栈内前面的元素,且栈顶元素>当前元素,即栈顶元素作为最小数的区间范围可以确定:栈顶元素对应的下标~当前元素之前),对栈顶元素计算完之后,将其弹出,然后继续对栈顶元素进行判断。直到栈空。
类似的题目有:
接雨水:(单调递减栈):就是当遇到比栈顶元素大的元素时,将栈顶弹出,这时可以计算当前元素和新的栈顶之间的雨水,继续判断当前元素是否比栈顶元素小,如果是的话就弹出,如果栈空,则只把当前元素入栈,否则继续计算当前元素和新的栈顶之间的雨水)、
求最大矩形面积(单调递增栈):计算目标是“计算以不同列作为矩形高度的最大矩形的面积,即求以不同列作为最小数的区间范围”,因此当遇到比栈顶小的元素时,可以计算该范围(因为栈内单调增,可以保证前面的元素小于栈顶元素(且前面挨着的元素为栈顶元素在数组中向左的第一个比他小的元素,即中间的元素都比他大,因为他一定会将之前比他大的元素弹出栈,因此它在这个范围内为最小值),即可以确定区间左边界,当前元素是栈顶元素右边的第一个小于栈顶元素的元素(否则栈顶不会在栈内),即栈顶元素到当前元素之间的元素都比栈顶大,可以确定区间右边界)
求区间最小数乘区间和的最大值(单调增)
题目描述
给定一个数组,要求选出一个区间, 使得该区间是所有区间中经过如下计算的值最大的一个:区间中的最小数 * 区间所有数的和。
数组中的元素都是非负数。
输入两行,第一行n表示数组长度,第二行为数组序列。输出最大值。
输入
3
6 2 1 3**3**28
输出
36
解释:满足条件区间是[6] = 6 * 6 = 36;
代码如下(和最大矩形面积一样)。
技巧:前后设置哨兵(扩展数组,长度加2,高度均为0),前哨兵(1、作为最小左边界(如果栈内没有其他的比栈顶小的第一个元素的话,那么哨兵的位置+1=1即为最小左边界);2、减少非空判断,哨兵值为0,不会存在比0小的数组元素,因此栈不会为空,在进行取栈顶时不需要进行栈非空判断);后哨兵(当最后一个数组元素判断完之后,栈可能不为空,仍有其他待计算的列,而后哨兵高度为0,一定是小于栈顶元素的第一个元素,会触发对栈顶元素的计算,其右边界相当于后哨兵位置-1,即原数组最后一个元素的位置)
class Solution {public int largestRectangleArea(int[] heights) {Stack stack=new Stack();int[] newHeight=new int[heights.length+2];newHeight[0]=0;for(int i=0;i
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!