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

    1. 每日温度

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

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

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

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

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

  • 当前遍历的元素Ti小于栈顶元素Tst.top()的情况
  • 当前遍历的元素Ti等于栈顶元素Tst.top()的情况
  • 当前遍历的元素Ti大于栈顶元素Tst.top()的情况

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

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

(2)Ti<Tst.top():不是栈顶的result位置,直接入栈。

(3)Ti==Tst.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,然后更新resultj,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;
    }
};
相关推荐
伊玛目的门徒5 小时前
试用leetcode之典中典 二数之和问题
java·算法·leetcode
Jerry5 小时前
LeetCode 226. 翻转二叉树
算法
想做小南娘,发现自己是女生喵6 小时前
【无标题】
数据结构·算法
Kx_Triumphs8 小时前
HDU4348 To the moon(主席树区间修改模板)
算法·题解
旖-旎8 小时前
《LeetCode647 回文子串 || LeetCode 5 最长回文子串》
c++·算法·leetcode·动态规划·哈希算法
轻颂呀9 小时前
约瑟夫环问题
算法
凤凰院凶涛QAQ11 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
科技大视界11 小时前
投资AI项目,传统尽调不够用了——李章虎律师拆解算法、数据、算力三大雷区
人工智能·算法·数据挖掘
郝学胜-神的一滴11 小时前
算法实战:最小k个数——大顶堆的优雅解法
开发语言·数据结构·c++·python·程序人生·算法·排序算法