力扣 739. 每日温度 & 496.下一个更大元素 I

    1. 每日温度

穷举的话就是从当前元素往后找比自己大的第一个元素,时间复杂度O(n^2)。
然后在看单调栈的解法。 就能感受出单调栈的巧妙。这道题主要熟悉单调栈这个数据结构。

单调栈:分为单调递增栈和单调递减栈。单调递增:栈顶元素总是小于(或等于)栈中所有其他元素。有时候根据题意,可能只有小于。

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

主要要模拟弄清这个过程,那么程序就好写了。

这里需要使用单调递增栈。

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

搞清楚上面3种情况的操作:

(1)T[i]>T[st.top()]:目前是单调递增栈,都遵循这3个操作的话,i是top元素右边比自己大的第一个元素,所以可以得到result[st.top()]。现在得让i入栈,要满足这个栈仍然是单增栈,所以top出栈之后,还要接着比较栈顶和i,如果i还是>top的话,还得pop,并得到得到result[st.top()]......一直到栈顶元素比i大,既满足了单增栈(pop(),push()),又得到了栈头开始连续的这些比i小的元素的result值。

(2)T[i]<T[st.top()]:不是栈顶的result位置,直接入栈。

(3)T[i]==T[st.top()]:同样不是栈顶的result位置,入栈。

模拟一下过程更直观:

最后没有元素了,栈里面还剩一些元素,这些元素后面没有比他们大的了,所以按照题意直接是0,所以一开始都初始化为0.

代码如下。while是T【i】>T【top】的情况,因为情况1出栈、得到result之后就入栈,情况2和3直接入栈,所以s.push(i)是共有的:

简化前:

cpp 复制代码
if (T[i] < T[st.top()]) {                       // 情况一
                st.push(i);
            } else if (T[i] == T[st.top()]) {               // 情况二
                st.push(i);
            } else {
                while (!st.empty() && T[i] > T[st.top()]) { // 情况三
                    result[st.top()] = i - st.top();
                    st.pop();
                }
                st.push(i);
cpp 复制代码
//简化后:
class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
           int n=temperatures.size();
           vector<int> result(n,0);
           stack<int> s;
           s.push(0);
           for(int i=1;i<n;++i){
                int top=s.top();
                while(temperatures[i]>temperatures[top]){   //一直大于栈顶,出栈
                    result[top]=i-top;
                    s.pop();
                    if(s.empty())break;
                    top=s.top();
                }
                s.push(i);  //入栈
           }
           return result;
    }
};
  • 496.下一个更大元素 I

设置单调栈,同样是递增的,而后遍历nums2,根据上面的逻辑来进行出栈入栈,同时检查当前元素i在nums1中的下标j,然后更新result[j],j不存在不操作。检查i是否存在于nums1以及其下标很适合用map,即保存nums1各元素和下标的映射。

因为如果不存在下一个更大元素,那么本次查询的答案是 -1 。所以一开始都更新为-1,没有找到下一个更大元素的时候不会更新,保持为-1.

代码如下:

cpp 复制代码
class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int n1=nums1.size();
        int n2=nums2.size();
        vector<int> result(n1,-1);
        map<int,int> nums1Map;
        for(int i=0;i<n1;++i)nums1Map.insert(pair<int,int>(nums1[i],i));
        stack<int> s;
        for(int i=0;i<n2;++i){
            while(!s.empty() && nums2[i]>nums2[s.top()]){
                map<int,int>::iterator it=nums1Map.find(nums2[s.top()]);
                if(it!=nums1Map.end())result[it->second]=nums2[i];
                s.pop();
            }
            s.push(i);
        }
        return result;
    }
};
相关推荐
思捻如枫26 分钟前
C++数据结构和算法代码模板总结——算法部分
数据结构·c++
嘉陵妹妹30 分钟前
深度优先算法学习
学习·算法·深度优先
GalaxyPokemon1 小时前
LeetCode - 53. 最大子数组和
算法·leetcode·职场和发展
小猫咪怎么会有坏心思呢1 小时前
华为OD机考 - 水仙花数 Ⅰ(2025B卷 100分)
数据结构·链表·华为od
hn小菜鸡2 小时前
LeetCode 1356.根据数字二进制下1的数目排序
数据结构·算法·leetcode
zhuiQiuMX2 小时前
分享今天做的力扣SQL题
sql·算法·leetcode
music&movie3 小时前
算法工程师认知水平要求总结
人工智能·算法
laocui14 小时前
Σ∆ 数字滤波
人工智能·算法
yzx9910134 小时前
Linux 系统中的算法技巧与性能优化
linux·算法·性能优化
全栈凯哥4 小时前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表