力扣 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;
    }
};
相关推荐
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
pianmian14 小时前
python数据结构基础(7)
数据结构·算法
好奇龙猫6 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
sp_fyf_20247 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
ChoSeitaku7 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
偷心编程7 小时前
双向链表专题
数据结构
香菜大丸7 小时前
链表的归并排序
数据结构·算法·链表
jrrz08287 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time7 小时前
golang学习2
算法
@小博的博客7 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习