单调栈

1. 下一个更大元素 I

1.1 题目描述

给你两个 没有重复元素 的数组$nums1$$nums2$,其中$nums1$$nums2$的子集。
请你找出$nums1$中每个元素在$nums2$中的下一个比其大的值。
$nums1$中数字$x$的下一个更大元素是指$x$$nums2$中对应位置的右边的第一个比$x$大的元素。如果不存在,对应位置输出 $-1$

输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
    对于 num1 中的数字 4 ,你无法在第二个数组中找到下一个更大的数字,因此输出 -1 。
    对于 num1 中的数字 1 ,第二个数组中数字1右边的下一个较大数字是 3 。
    对于 num1 中的数字 2 ,第二个数组中没有下一个更大的数字,因此输出 -1 。
输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
    对于 num1 中的数字 2 ,第二个数组中的下一个较大数字是 3 。
    对于 num1 中的数字 4 ,第二个数组中没有下一个更大的数字,因此输出 -1 。

1.2 解题思路 单调栈

单调栈实际上就是栈,只是利用了一些巧妙的逻辑,使得每次新元素入栈后,栈内的元素都保持有序(单调递增或单调递减)。单调栈用途不太广泛,只处理一种典型的问题,叫做$ Next Greater Element$

func nextGreaterElement(nums1 []int, nums2 []int) []int {
	res := make([]int, len(nums1))
	stack := make([]int, 0)
	mp := make(map[int]int)
	// 单调栈
	for _, num := range nums2 {
	    // 栈内元素小于新元素 栈内元素出栈
		for len(stack)>0 && num > stack[len(stack)-1] {
			mp[stack[len(stack)-1]] = num
			stack = stack[:len(stack)-1]
		}
		// 新元素入栈
		stack = append(stack, num)
	}
	for i, num := range nums1 {
		if _, ok := mp[num]; ok {
			res[i] = mp[num]
		} else {
			res[i] = -1
		}
	}
	return res
}

leetcode496. 下一个更大元素 I

2.下一个更大元素 II

2.1 题目描述

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 $x$ 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 $-1$

输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数; 
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。

2.2 解题思路

循环两遍数组,单调栈。

func nextGreaterElements(nums []int) []int {
	n := len(nums)
	stack := make([]int, 0)
	res := make([]int, n)
	for i := range res {
		res[i] = -1
	}
	for i := 0; i < 2*n-1; i++ {
	    // 出栈
		for len(stack) > 0 && nums[i%n] > nums[stack[len(stack)-1]] {
			res[stack[len(stack)-1]] = nums[i%n]
			stack = stack[:len(stack)-1]
		}
		// 入栈
		stack = append(stack, i%n)
	}
	return res
}

leetcode 503. 下一个更大元素 II

3. 每日温度

3.1 题目描述

请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 $0$ 来代替。

给定一个列表temperatures = [73, 74, 75, 71, 69, 72, 76, 73],
你的输出应该是[1, 1, 4, 2, 1, 1, 0, 0]。

3.2 解题思路

单调栈。

func dailyTemperatures(T []int) []int {
	n := len(T)
	stack := []int{}
	res := make([]int, n)
	for i := 0; i < n; i++ {
	    // 出栈
		for len(stack) > 0 && T[i] > T[stack[len(stack)-1]] {
			res[stack[len(stack)-1]] = i - stack[len(stack)-1]
			stack = stack[:len(stack)-1]
		}
		// 入栈
		stack = append(stack, i)
	}
	return res
}

leetcode 739. 每日温度

posted @ 2021-05-29 22:15  白小白2020  阅读(48)  评论(0编辑  收藏  举报