LeetCode 503. 下一个更大元素 II
题目链接:503. 下一个更大元素 II
思路:我们可以使用单调栈解决本题,思路与上一篇博客的739. 每日温度一致。每次我们移动到数组中的一个新的位置,我们就将当前单调栈中所有对应值小于nums[i]的下标弹出单调栈,这些值的下一个更大元素即为 nums[i]。随后我们将当前最大的元素入栈。
在本题中,关于遍历两个数组的状况,我们不需要直接操作将该循环数组“拉直”,而只需要在处理时对下标取模即可。
go版本:
func nextGreaterElements(nums []int) []int {
n := len(nums)
res := make([]int, n)
for i := range res {
res[i] = -1
}
stack := []int{}
for i := 0; i < n*2-1; i++ {
for len(stack) > 0 && nums[stack[len(stack)-1]] < nums[i % n] {
res[stack[len(stack)-1]] = nums[i % n]
stack = stack[:len(stack)-1]
}
stack = append(stack, i % n)
}
return res
}
LeetCode 42. 接雨水
题目链接:42. 接雨水
思路:经典中的经典——接雨水。本题使用双指针的方法来做,因为双指针思想直接一些。
首先要找出两个“标兵”,左边是当前列的左边的最高的列高度,右边是当前列的右边的最高的列高度。这样只需要遍历height[1, n-2]的范围即可,因为首尾两端的列不管多高都无法装水。因为已经得到第i列的左边(不包括自身)和右边(也不包括自身)的最高列的高度,那此时这两个“标兵”(即左边最高列和右边最高列)之间的范围就可以“接雨水”了,此处还有一个细节,两个最高列中还需要选较低者,因为能接多少水的上限是高度较低的一列决定的。
综上所述,找当前列左右两侧最高的两列中偏矮的那一列(记为temp)与当前列进行比较,如果temp大于当前列,则当前列能存(temp-height[i])的水量,反之,temp小于等于当前列高度时,是存不了水的。
go版本:
func trap(height []int) int {
res := 0
n := len(height)
maxLeft, maxRight := 0, 0
left := 1
right := n-2
for i:=1; i<n-1; i++ {
// maxLeft是由height[left-1]更新过来的,maxRight是由height[right+1]更新过来的,谁更低选谁
if height[left-1] < height[right+1] {
maxLeft = max(maxLeft, height[left-1])
if maxLeft > height[left] {
res += maxLeft - height[left]
}
left++
} else {
maxRight = max(maxRight, height[right+1])
if maxRight > height[right] {
res += maxRight - height[right]
}
right--
}
}
return res
}
func max(i, j int) int {
if i>j {
return i
}
return j
}