文章目录
- day58学习内容
- 一、每日温度
- 1.1、思路
- 1.2、代码
- 二、下一个更大元素I
- 2.1、思路
- 2.2、代码
- 总结
- 1.感想
- 2.思维导图
day58学习内容
day58主要内容
- 每日温度
- 下一个更大元素I
声明
本文思路和文字,引用自《代码随想录》
一、每日温度
739.原题链接
1.1、思路
-
使用单调栈:
- 栈的特性: 我们使用一个栈来帮助记录那些还没有找到更高温度的日子。这个栈是单调递减的,意味着栈顶的温度总是最低的。
-
遍历数组:
- 从数组的第一个元素开始遍历。
- 对于每个元素(代表当前天的温度),我们比较它与栈顶元素(栈中元素存储的是温度的索引,因此要回数组中取值)代表的温度。
-
温度比较:
- 如果当前温度小于或等于栈顶元素对应的温度,我们将当前温度的索引入栈。这表示还没有找到更高的温度,需要继续等待。
- 如果当前温度大于栈顶元素对应的温度,这表示我们找到了一个更高的温度。我们将进行以下步骤:
- 弹出栈顶元素。
- 计算这一天与栈顶元素代表的天数之间的差,即为栈顶元素所需等待的天数,记录在结果中。
- 继续检查新的栈顶元素,直到找到一个栈顶元素对应的温度大于当前温度,或者栈变空。
-
重复上述步骤:
- 对数组中每个元素重复上述步骤。
-
处理栈中剩余元素:
- 遍历完成后,栈中可能还有一些元素。这些元素对应的天数之后没有更高的温度出现,它们对应的结果应该是0(通常这在初始化结果数组时已经默认设置)。
1.2、代码
class Solution {public int[] dailyTemperatures(int[] temperatures) {// 获取温度数组的长度int lens = temperatures.length;// 初始化结果数组,用于存储每天后需要等待多少天才有更高的温度int[] res = new int[lens];// 创建一个双端队列作为栈使用,存储数组索引Deque<Integer> stack = new LinkedList<>();// 先将第一天的索引入栈stack.push(0);// 从第二天开始遍历温度数组for (int i = 1; i < lens; i++) {// 检查当前天的温度是否小于或等于栈顶天的温度if (temperatures[i] <= temperatures[stack.peek()]) {// 如果是,将当前天的索引入栈,因为还没找到更高温度stack.push(i);} else {// 如果当前天的温度大于栈顶天的温度while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {// 计算等待天数,当前天索引减去栈顶天的索引res[stack.peek()] = i - stack.peek();// 栈顶元素出栈,因为已找到更高的温度stack.pop();}// 将当前天的索引入栈,因为可能需要比较后续的天气stack.push(i);}}// 栈中剩余的索引代表的天数将不会有更高的温度,其结果数组中默认为0return res;}
}
二、下一个更大元素I
496.原题链接
2.1、思路
给定两个数组 nums1
和 nums2
,其中 nums2
是 nums1
的超集。对于 nums1
中的每一个元素,需要在 nums2
中找到该元素对应位置之后的第一个比它大的元素。如果不存在,则结果为 -1
。
-
哈希表存储:
- 首先,对
nums1
的元素建立一个映射,记录每个元素在nums1
中的位置,便于最后构建结果数组。
- 首先,对
-
单调栈使用:
- 使用一个单调栈来处理
nums2
。栈里存储的是nums2
的元素索引,这些索引在栈中的顺序由栈底到栈顶是对应值递减的。 - 遍历
nums2
,对于每个元素,如果它小于或等于栈顶元素的值,则直接将其索引压入栈中。 - 如果当前元素大于栈顶元素的值,这说明我们找到了栈顶元素的“下一个更大元素”。此时,将栈顶元素弹出,并在结果映射中更新该元素的“下一个更大元素”为当前元素。重复此操作,直到当前元素不再大于新的栈顶元素或栈为空,然后将当前元素的索引压入栈中。
- 使用一个单调栈来处理
-
构建结果:
- 通过上述过程,栈中的元素会在遇到比它大的元素时被逐个弹出,并更新结果数组。最终,每当一个元素被弹出栈时,我们就确定了它的下一个更大元素。
- 根据
nums1
中元素的原始索引位置,从结果映射中取出答案填充到最终输出的结果数组中。
2.2、代码
class Solution {public int[] nextGreaterElement(int[] nums1, int[] nums2) {// 创建一个栈来保存数组元素的索引Stack<Integer> temp = new Stack<>();// 初始化结果数组,所有元素默认值为-1(代表没有找到下一个更大的元素)int[] res = new int[nums1.length];Arrays.fill(res, -1);// 创建一个哈希表来记录nums1中每个元素的索引,便于后续快速查找HashMap<Integer, Integer> hashMap = new HashMap<>();for (int i = 0; i < nums1.length; i++) {hashMap.put(nums1[i], i);}// 将nums2的第一个元素的索引入栈temp.add(0);// 遍历nums2中的所有元素for (int i = 1; i < nums2.length; i++) {// 如果当前元素小于等于栈顶元素,将其索引入栈if (nums2[i] <= nums2[temp.peek()]) {temp.add(i);} else {// 否则,循环判断栈顶元素与当前元素的大小while (!temp.isEmpty() && nums2[temp.peek()] < nums2[i]) {// 如果栈顶元素小于当前元素,弹出栈顶元素if (hashMap.containsKey(nums2[temp.peek()])) {// 检查弹出的栈顶元素是否存在于nums1中Integer index = hashMap.get(nums2[temp.peek()]);// 更新nums1中对应元素的结果为当前元素(下一个更大元素)res[index] = nums2[i];}temp.pop();}// 将当前元素索引入栈temp.add(i);}}// 返回结果数组return res;}
}
总结
1.感想
- 单调栈第一天,冲
- 单调栈具体的模拟过程,卡尔的视频讲的很清楚。建议去看视频,这里不画图了,太复杂了。
2.思维导图
本文思路引用自代码随想录,感谢代码随想录作者。