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

Leetcode 739. 每日温度

题目链接:Leetcode 739. 每日温度
题目描述: 给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

思路: 本题是单调栈的经典题目。单调栈的应用范围:在一维数组中,寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置。

代码如下:

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 { // 否则不断比较栈顶元素,并计算结果
                while ((!st.empty() && T[i] > T[st.top()])) {
                    result[st.top()] = i - st.top();
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;
    }
};
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

Leetcode 496.下一个更大元素 I

题目链接: Leetcode 496.下一个更大元素 I
题目描述: nums1 中数字 x 的 下一个更大元素 是指 xnums2 中对应位置 右侧 的 第一个 比 x 大的元素。给你两个 没有重复元素 的数组 nums1nums2 ,下标从 0 开始计数,其中nums1nums2 的子集。

  • 对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。
  • 如果不存在下一个更大元素,那么本次查询的答案是 -1 。返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。

思路: 本题的数据范围是 1 0 3 10^3 103,因此可以使用暴力解决。

代码如下:(暴力)

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int m = nums2.size();
        vector<int> res(n);
        for (int i = 0; i < n; i++) {
            int j = 0;
            while (j < m && nums2[j] != nums1[i]) { // 先去nums2找到nums1中的元素
                j++;
            }
            int k = j + 1; // 寻找比nums2[j]大的元素
            while (k < m && nums2[k] < nums2[j]) {
                k++;
            }
            // 找到则更新,否则为-1
            res[i] = k < m ? nums2[k] : -1;
        }
        return res;
    }
};
  • 时间复杂度: O ( n × m ) O(n×m) O(n×m),其中 nnums1的长度,mnums2的长度。

  • 空间复杂度: O ( 1 ) O(1) O(1)

本题如果使用单调栈,还是比较难的。因为本题是两个数组,我们需要利用哈希表的映射关系来实现单调栈。
代码如下:(单调栈)

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        stack<int> st;
        int n = nums1.size();
        int m = nums2.size();
        vector<int> result(n, -1);
        if (n == 0)
            return result;
        unordered_map<int, int> umap; // key:下标元素,value:下标
        for (int i = 0; i < n; i++) {
            umap[nums1[i]] = i;
        }
        st.push(0);
        for (int i = 1; i < nums2.size(); i++) {
            if (nums2[i] <=
                nums2[st.top()]) { // 如果当前元素没有栈顶元素大,加到栈里
                st.push(i);
            } else {
                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;
    }
};
  • 时间复杂度: O ( n + m ) O(n+m) O(n+m) ,其中 nnums1的长度,mnums2的长度。
  • 空间复杂度: O ( n ) O(n) O(n)

总结: 单调栈之前没接触过,还需要多练习。单调栈的应用范围:在一维数组中,寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置。

最后,如果文章有错误,请在评论区或私信指出,让我们共同进步!

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值