> 文章列表 > 代码随想录算法训练营第五十八天 | 739. 每日温度、496. 下一个更大元素 I

代码随想录算法训练营第五十八天 | 739. 每日温度、496. 下一个更大元素 I

代码随想录算法训练营第五十八天 | 739. 每日温度、496. 下一个更大元素 I

739. 每日温度

单调栈的使用:通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了,时间复杂度为O(n)。

单调栈本质:空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。

单调栈里存放的元素是下标i,如果需要使用元素,则使用T[i]获取元素

单调栈里元素的递增/递减?

顺序的描述为 从栈头到栈底的顺序

本题使用递增循序(再强调一下是指从栈头到栈底的顺序),因为只有递增的时候,栈里要加入一个元素i的时候,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i。

如果求一个元素右边第一个更大元素,单调栈就是递增的,如果求一个元素右边第一个更小元素,单调栈就是递减的。

使用单调栈主要有三个判断条件:

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {stack<int> single;vector<int> result(temperatures.size(), 0);single.push(0);for (int i = 1; i < temperatures.size(); i++) {//当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况if (temperatures[i] < temperatures[single.top()]) {single.push(i);} else //当前遍历的元素T[i]等于栈顶元素T[st.top()]if (temperatures[i] == temperatures[single.top()]) {single.push(i);} else //当前遍历的元素T[i]大于栈顶元素T[st.top()]{while (!single.empty() && temperatures[i] > temperatures[single.top()]) {result[single.top()] = i - single.top();single.pop();}single.push(i);}}return result;}
};

496. 下一个更大元素 I

 result数组初始化应该为-1,题目说如果不存在对应位置就输出 -1 ,所以result数组如果某位置没有被赋值,那么就应该是是-1,所以就初始化为-1。

注意题目中说是两个没有重复元素 的数组 nums1 和 nums2

没有重复元素,可以用map来做映射。根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过。

C++中,当需要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的。

unordered_map<int, int> umap; // key:下标元素,value:下标
for (int i = 0; i < nums1.size(); i++) {umap[nums1[i]] = i;
}

使用单调栈,首先要想单调栈是从大到小还是从小到大。

栈头到栈底的顺序,要从小到大,也就是保持栈里的元素为递增顺序。只要保持递增,才能找到右边第一个比自己大的元素。

接下来就要分析如下三种情况:

  1. 情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况

此时满足递增栈(栈头到栈底的顺序),所以直接入栈。

  1. 情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况

如果相等的话,依然直接入栈,因为我们要求的是右边第一个比自己大的元素,而不是大于等于!

  1. 情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

此时如果入栈就不满足递增栈了,这也是找到右边第一个比自己大的元素的时候。

判断栈顶元素是否在nums1里出现过,(注意栈里的元素是nums2的元素),如果出现过,开始记录结果。

while (!st.empty() && nums2[i] > nums2[st.top()]) {// 看map里是否存在这个元素    if (umap.count(nums2[st.top()]) > 0) { // 根据map找到nums2[st.top()] 在 nums1中的下标int index = umap[nums2[st.top()]]; result[index] = nums2[i];}st.pop();
}
st.push(i);
class Solution {
public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {stack<int> single;vector<int> result(nums1.size(), -1);if (nums1.size() == 0) return result;unordered_map<int, int> umap;for (int i = 0; i < nums1.size(); i++) {umap[nums1[i]] = i;} single.push(0);for (int i = 1; i < nums2.size(); i++) {if (nums2[i] < nums2[single.top()]) {single.push(i);} else if (nums2[i] == nums2[single.top()]) {single.push(i);} else {while (!single.empty() && nums2[i] > nums2[single.top()]) {if (umap.count(nums2[single.top()]) > 0) {int index = umap[nums2[single.top()]];result[index] = nums2[i];}single.pop();}single.push(i);}}return result;}
};