今日内容:
资料来源:
题目
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73] 输出: [1,1,4,2,1,1,0,0]
示例 2:
输入: temperatures = [30,40,50,60] 输出: [1,1,1,0]
示例 3:
输入: temperatures = [30,60,90] 输出: [1,1,0]
提示:
单调栈,顾名思义,和单调队列一样,是一种在栈的基础上维护内部数据的单调性的数据结构。它所代表的题目一般具有“求左/右边的第一个更大元素”的特征。
Go语言没有自己实现的栈,一般如果需要用栈的话有三种方案:自己实现栈,用切片模拟栈和用
container/list
双向链表来模拟栈。之后的所有单调栈题目都会用第二种方法。
以维护一个从栈顶到栈底单调递增的单调栈为例,每次元素试图入栈时,都需要和栈顶元素进行比较。如果元素和栈顶元素相同,需要根据题目要求确实是否进入栈;如果元素大于栈顶元素,则出栈一次后继续比较,直到栈空或者栈顶元素比入栈元素要大;如果元素小于栈顶元素,则直接入栈。
就本题来说,它要找的是当前元素右侧比它大的第一个元素和它的距离,那么单调栈内可以存元素的下标,从而再出栈时同时获取元素的下标和比该元素大的元素的下标。另外,本题如果元素相等也要入栈,因为元素相等也要找那个更大的元素。
gofunc dailyTemperatures(temperatures []int) []int {
result := make([]int, len(temperatures))
stack := []int{0}
for i := 1; i < len(temperatures); i++ {
top := stack[len(stack) - 1]
if temperatures[i] > temperatures[top] { // 如果栈顶元素小于新元素 就移除栈顶元素 将新元素加入
for len(stack) != 0 && temperatures[i] > temperatures[top] { // len(stack) != 0 经常忘
result[top] = i - top
stack = stack[:len(stack) - 1] // 移除最后的元素
if len(stack) != 0 {
top = stack[len(stack) - 1]
}
}
stack = append(stack, i)
} else if temperatures[i] <= temperatures[top] { // 栈顶元素大于等于新元素 直接加入
stack = append(stack, i)
}
}
return result
}
题目
nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。
给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。
对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。
返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。
示例 1:
输入:nums1 = [4,1,2], nums2 = [1,3,4,2]. 输出:[-1,3,-1] 解释:nums1 中每个值的下一个更大元素如下所述: - 4 ,用加粗斜体标识,nums2 = [1,3, 4 ,2]。不存在下一个更大元素,所以答案是 -1 。 - 1 ,用加粗斜体标识,nums2 = [ 1 ,3,4,2]。下一个更大元素是 3 。 - 2 ,用加粗斜体标识,nums2 = [1,3,4, 2 ]。不存在下一个更大元素,所以答案是 -1 。
示例 2:
输入:nums1 = [2,4], nums2 = [1,2,3,4]. 输出:[3,-1] 解释:nums1 中每个值的下一个更大元素如下所述: - 2 ,用加粗斜体标识,nums2 = [1, 2 ,3,4]。下一个更大元素是 3 。 - 4 ,用加粗斜体标识,nums2 = [1,2,3, 4 ]。不存在下一个更大元素,所以答案是 -1 。
提示:
进阶:你可以设计一个时间复杂度为 O(nums1.length + nums2.length) 的解决方案吗?
这题和上一个题很像,但是在单调栈的处理之上又多了一层去nums1寻找元素位置的逻辑,其他的和上一题区别不大。
gofunc nextGreaterElement(nums1 []int, nums2 []int) []int {
result := make([]int, len(nums1))
resultMap := map[int]int{} // 存储nums1中的元素和下标对应关系
for i := range nums1 {
result[i] = -1 // 初始化 找不到就是-1
resultMap[nums1[i]] = i
}
stack := []int{0}
for i := 1; i < len(nums2); i++ {
top := stack[len(stack) - 1]
if nums2[i] > nums2[top] {
for len(stack) != 0 && nums2[i] > nums2[top] {
if val, ok := resultMap[nums2[top]]; ok {
result[val] = nums2[i]
}
stack = append(stack[:len(stack) - 1])
if len(stack) != 0 {
top = stack[len(stack) - 1]
}
}
stack = append(stack, i)
} else {
stack = append(stack, i)
}
}
return result
}
本文作者:御坂19327号
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!