力扣 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;
    }
};
相关推荐
yi0117 分钟前
LeetCode 3. 无重复字符的最长子串|不定长滑动窗口:什么时候更新最大值?
笔记·python·算法·leetcode·双指针·滑动窗口
y1su14 分钟前
Leetcode 单调栈模板
java·开发语言·数据结构·算法·leetcode
索尔~古德曼29 分钟前
CF(1400-1400&1300-1500)
算法
一只旭宝31 分钟前
树的家族全景:从二叉树到 B+ 树
数据结构
爱刷碗的苏泓舒36 分钟前
泰勒级数与泰勒展开:GNSS卫地距线性化、Jacobian矩阵与Hessian矩阵
线性代数·算法·矩阵·gnss·雅可比矩阵·卫地距线性化·海森矩阵
垆边人似月.43 分钟前
华为题:每日温度
数据结构·c++·算法
Sylvia-girl1 小时前
堆排序算法
算法·排序算法·c
Peregrine91 小时前
数据结构 - > 树和二叉树
数据结构·算法
我是人✓1 小时前
Java面向对象核心特性深度解析
java·前端·算法
j7~1 小时前
【算法】专题四.前缀和:一维二维模板,配套 LeetCode 真题,结合同余定理、哈希前缀和,搞定子数组与子矩阵区间求和问题。
数据结构·c++·算法·前缀和·优选算法