代码随想录训练营第58天|739.每日温度、496.下一个更大元素Ⅰ

739.每日温度、496.下一个更大元素Ⅰ

739.每日温度

对于每日温度,我们要求的是后面比今天气温高的一天。例如 假设气温是34 33 36 37.那么对于第一天,他的气温是34,比34高的气温是36,因此,我们返回2-0,也就是2.
对于此,我们可以利用两层for循环进行暴力求解,然而这种方法确实超时的,因此不再赘述。

对此,我们用单调栈进行求解。

单调栈是一种特殊的栈数据结构,它的特点是栈内元素保持单调递增或单调递减的顺序。在单调栈中,每个元素都会被压入栈中,并且在压入之前,会先将栈中比它小(或大)的元素弹出栈,以保证栈内元素的单调性。

单调栈常用于解决一些需要寻找最大值或最小值的问题,例如在一个数组中找到每个元素左边(或右边)第一个比它大(或小)的数。这种问题通常可以通过维护一个单调栈来解决,具体做法是将数组从左到右依次遍历,将每个元素压入栈中,并在压入之前弹出比它小(或大)的元素,同时记录下每个元素的答案。这样,最后得到的就是每个元素左边(或右边)第一个比它大(或小)的数。

这道题可以使用单调递减栈来解决,具体实现步骤如下:

1.创建一个空栈stack和一个空数组ans,用于存放答案。

2.从右到左遍历数组T,依次将每个元素压入栈中。

3.对于每个元素T[i],如果栈顶元素T[stack[-1]]比它小,那么将栈顶元素弹出栈,直到栈为空或者栈顶元素比它大。

4.如果栈为空,说明T[i]右边没有比它大的数,将ans[i]赋值为0。

5.如果栈不为空,说明栈顶元素是T[i]右边第一个比它大的数,将ans[i]赋值为栈顶元素T[stack[-1]]的下标减去i。

6.将i压入栈中。

7.遍历完整个数组之后,ans数组中存放的就是每个位置之后需要等待多少天才能等到比它更高的温度。

代码

class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
    int n = T.size();
    stack<int> s;
    vector<int> ans(n, 0);
    for (int i = n-1; i >= 0; i--) {
        while (!s.empty() && T[s.top()] <= T[i]) {
            s.pop();
        }
        if (!s.empty()) {
            ans[i] = s.top() - i;
        }
        s.push(i);
    }
    return ans;
}
};

496.下一个更大元素Ⅰ

这道题可以使用单调栈来解决。我们可以先遍历 nums2 数组,使用单调栈来找到每个元素的下一个更大元素,然后将结果存储到一个哈希表中。最后,我们可以遍历 nums1 数组,从哈希表中查找每个元素的下一个更大元素。

具体来说,我们可以使用一个栈来维护一个单调递减的序列,栈中存储的是 nums2 数组中的下标。当遍历到一个新的元素时,我们将栈顶元素与当前元素比较,如果栈顶元素小于当前元素,那么栈顶元素的下一个更大元素就是当前元素。我们可以将栈顶元素出栈,并将其下一个更大元素存储到哈希表中。重复这个过程,直到栈为空或者栈顶元素大于等于当前元素。最后,将当前元素的下标入栈。

最后,我们可以遍历 nums1 数组,从哈希表中查找每个元素的下一个更大元素。如果哈希表中存在该元素的下一个更大元素,就将其存储到结果数组中。否则,将 -1 存储到结果数组中。

时间复杂度:O(m+n),其中 m 和 n 分别是 nums1 和 nums2 的长度。需要遍历 nums2 数组两次,以及遍历 nums1 数组一次,因此时间复杂度为 O(m+n)。

空间复杂度:O(n),其中 n 是 nums2 的长度。需要使用一个哈希表来存储每个元素的下一个更大元素,因此空间复杂度为 O(n)。

代码

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int> result(nums1.size(),-1);
        stack<int> st;
        unordered_map<int,int> umap;
        for(int ii =0;ii<nums1.size();ii++)
            umap[nums1[ii]] = ii;
        st.push(nums2[0]);
        for(int ii =1;ii<nums2.size();ii++)
        {
            if(nums2[ii]>st.top())
                while(!st.empty()&&st.top()<nums2[ii])
                {
                    if(umap.count(st.top())>0)
                        result[umap[st.top()]] = nums2[ii];
                    st.pop();
                }
            st.push(nums2[ii]);
        }
        return result;
    }
};

你可能感兴趣的:(数据结构,leetcode,算法)