Day50:739. 每日温度、496.下一个更大元素 I

文章目录

    • 前言
    • 739. 每日温度
      • 思路
      • 代码实现
    • 496.下一个更大元素 I
      • 思路
      • 代码实现


前言

打卡断了几天,今天开始写单调栈。
单调栈顾名思义就是用一个栈保存元素,里面的元素大小是单调的,要么从小到大,要么从大到小。利用单调栈可以轻松找到一个元素两边离他最近的最大或最小元素,具体操作直接看题目。

739. 每日温度

题目链接

思路

题目要求查找某天温度之后是否还有出现比它大的温度值,有则返回它与当天的相隔天数。这就可以利用单调栈,栈内元素按照从栈头到栈底从小到大的顺序。
当栈内元素为空,把当前元素push进栈,再依次向后遍历,和栈顶元素比较。
比较会产生三种结果:

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

情况一:还没遍历到比它温度高的最近元素T[i],先保存当前温度
情况二:和情况一一样进栈
情况三:找到了栈顶元素之后的天数中比它大的最近元素T[i],他们两相隔天数就是i - st.top(),不过记得把栈顶元素pop出栈

代码实现

这里我先自己用了个pari元素分别保存坐标和温度,然后发现直接保存下标就好了,会更方便也不浪费内存。

  1. 用pair
class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        stack<pair<int,int>> st;
        vector<int> result(temperatures.size(),0);
        pair<int,int> tmp(0,temperatures[0]);
        st.push(tmp);
        for(int i=1;i<temperatures.size();i++){
            pair<int,int> tmp(i,temperatures[i]);
            while(!st.empty()&&temperatures[i]>st.top().second){
                result[st.top().first]=i-st.top().first;
                st.pop();             
            }
            st.push(tmp);
        }
        return result;
    }
};
  1. 直接保存下标
class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& T) {
        // 递增栈
        stack<int> st;
        vector<int> result(T.size(), 0);
        st.push(0);
        for (int i = 1; i < T.size(); i++) {
            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);
            }
        }
        return result;
    }
};

496.下一个更大元素 I

题目链接

思路

题目要求是从num2序列中找到num1的各个元素在num2中下一个最大元素的多少。

  1. 暴力搜寻法
    求num2的下一个最大元素也是用单调栈就可以解决。
    再用两个for循环遍历num1,和num2,就可以得到最大元素位置。这个方法时间复杂度稍微高一点,但是便于理解。
  2. 直接查找法
    用unordered_map来保存num1的元素,在用单调栈计算num2的下一个最大元素的同时,直接用if (umap.count(nums2[st.top()]) > 0)来判断num1内是否有st.top(这个元素),没有就直接pop出去,反正不需要记录结果。

代码实现

  1. 暴力搜寻法
class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        stack<int> st;
        vector<int> tmp(nums2.size(),-1);
        vector<int> result(nums1.size());
        st.push(0);
        for(int i=1;i<nums2.size();i++){
            while(!st.empty()&&nums2[i]>nums2[st.top()]){
                tmp[st.top()]=nums2[i];
                st.pop();
            }
            st.push(i);
        }
        for(int i=0;i<nums1.size();i++){
            for(int j=0;j<nums2.size();j++){
                if(nums1[i]==nums2[j]){
                    result[i]=tmp[j];
                }
            }
        }
        return result;
    }
};
  1. 直接查找法
class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        stack<int> st;
        vector<int> result(nums1.size(), -1);
        if (nums1.size() == 0) return result;

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

你可能感兴趣的:(算法,leetcode)