84. 柱状图中最大的矩形
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例1
输入: heights = [2,1,5,6,2,3]
输出: 10
解释: 最大的矩形为图中红色区域,面积为 10
解题流程1
func largestRectangleArea(heights []int) int {
statck:=[]int{}
sum:=0
for i:=0;i<len(heights);i++{
for len(statck)>0 && heights[i]<heights[statck[len(statck)-1]]{
w:=i-statck[len(statck)-1]
h:=heights[statck[len(statck)-1]]
statck=statck[:len(statck)-1]
sum=max(sum,w*h)
}
statck=append(statck,i)
}
return sum
}
func max(a,b int)int{
if a>b{
return a
}
return b
}
解题分析1
按照上面的方法,发现部分通过。
根据测试用例,可以想到有一种情况:如果数据本身就是递增排序的。那么栈里面的元栈顶到栈底是:4,2
这样始终无法进入上述题解中的for循环
解题流程2
func largestRectangleArea(heights []int) int {
stack:=[]int{}
temp:=[]int{}
sum:=0
temp=append(temp,0)
temp=append(temp,heights...)
temp=append(temp,0)
for i:=0;i<len(temp);i++{
for len(stack)>0 && temp[i]<temp[stack[len(stack)-1]]{
h:=temp[stack[len(stack)-1]]
stack=stack[:len(stack)-1]
w:=i-stack[len(stack)-1]-1
sum=max(sum,w*h)
}
stack=append(stack,i)
}
return sum
}
func max(a,b int)int{
if a>b{
return a
}
return b
}
解题分析2
数组前后添加了哨兵,解决上述存在的问题
739. 每日温度
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例1
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]
解题流程1
func dailyTemperatures(temperatures []int) []int {
stack:=[]int{}
res:=make([]int,len(temperatures))
for i:=0;i<len(temperatures);i++{
value:=0
if len(stack)>0 && temperatures[i]>temperatures[stack[len(stack)-1]]{
value=i-stack[len(stack)-1]
res[stack[len(stack)-1]]=value
stack=stack[:len(stack)-1]
}
stack=append(stack,i)
}
return res
}
解题分析1
首先本题首先想到的是暴力,双层for循环,第一层循环定位当前温度,第二层循环定位在当前温度数组中寻找大于当前温度的温度。
上述方法是时间复杂度较高。
由于当前元素始终是找大于当前温度的温度,考虑到空间换时间,想到了单调栈,使用栈存储温度的下标。
因此,写出上面的方法,部分通过。
问题点在于,当遇到一个较高温度的时候,只考虑比前一个温度值高,而没有考虑她可能比早之前的某些温度也高。因此,导致早之前的温度值没被刷新。
解题流程2
func dailyTemperatures(temperatures []int) []int {
stack:=[]int{}
res:=make([]int,len(temperatures))
for i:=0;i<len(temperatures);i++{
value:=0
for len(stack)>0 && temperatures[i]>temperatures[stack[len(stack)-1]]{
value=i-stack[len(stack)-1]
res[stack[len(stack)-1]]=value
stack=stack[:len(stack)-1]
}
stack=append(stack,i)
}
return res
}
解题分析2
通过对未通过的测试用例分析,将内层循环中的if 改为for,实现对早之前温度值的刷新。
503. 下一个更大元素 II
给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。
数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。
示例1
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
解题流程
func nextGreaterElements(nums []int) []int {
stack:=[]int{}
nums=append(nums,nums...)
res:=make([]int,len(nums))
for i:=0;i<len(nums);i++{
res[i]=-1
}
for i:=0;i<len(nums);i++{
for len(stack)>0 && nums[i]>nums[stack[len(stack)-1]]{
res[stack[len(stack)-1]]=nums[i]
stack=stack[:len(stack)-1]
}
stack=append(stack,i)
}
return res[:len(nums)/2]
}