2024-05-05
Go & Python & 算法
00

目录

1 LeetCode739 每日温度
2 LeetCode496 下一个更大元素 Ⅰ

今日内容:

  1. LeetCode739 每日温度
  2. LeetCode496 下一个更大元素 Ⅰ

资料来源:

  1. 代码随想录 | LeetCode739 每日温度
  2. 代码随想录 | LeetCode496 下一个更大元素 Ⅰ

1 LeetCode739 每日温度

题目

给定一个整数数组 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]

提示:

  • 1 <= temperatures.length <= 10510^5
  • 30 <= temperatures[i] <= 100

单调栈,顾名思义,和单调队列一样,是一种在栈的基础上维护内部数据的单调性的数据结构。它所代表的题目一般具有“求左/右边的第一个更大元素”的特征。

Go语言没有自己实现的栈,一般如果需要用栈的话有三种方案:自己实现栈,用切片模拟栈和用container/list双向链表来模拟栈。之后的所有单调栈题目都会用第二种方法。

以维护一个从栈顶到栈底单调递增的单调栈为例,每次元素试图入栈时,都需要和栈顶元素进行比较。如果元素和栈顶元素相同,需要根据题目要求确实是否进入栈;如果元素大于栈顶元素,则出栈一次后继续比较,直到栈空或者栈顶元素比入栈元素要大;如果元素小于栈顶元素,则直接入栈。

就本题来说,它要找的是当前元素右侧比它大的第一个元素和它的距离,那么单调栈内可以存元素的下标,从而再出栈时同时获取元素的下标和比该元素大的元素的下标。另外,本题如果元素相等也要入栈,因为元素相等也要找那个更大的元素。

go
func 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 }

2 LeetCode496 下一个更大元素 Ⅰ

题目

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 。

提示:

  • 1 <= nums1.length <= nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 10410^4
  • nums1和nums2中所有整数 互不相同
  • nums1 中的所有整数同样出现在 nums2 中

进阶:你可以设计一个时间复杂度为 O(nums1.length + nums2.length) 的解决方案吗?

这题和上一个题很像,但是在单调栈的处理之上又多了一层去nums1寻找元素位置的逻辑,其他的和上一题区别不大。

go
func 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 许可协议。转载请注明出处!