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

LeetCode 739 每日温度

题目链接:https://leetcode.cn/problems/daily-temperatures/

思路:

方法一:暴力解法

两个for循环,一个遍历数组,一个去找当前遍历数值的右边第一个比它大的值的下标

代码:
class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int>result;

        for(int i = 0; i < temperatures.size(); i++)
        {
            for(int j = i + 1; j < temperatures.size(); j++)
            {
                int index = 0;
                if(temperatures[j] > temperatures[i])
                {
                    index = j - i;
                    result.push_back(index);
                    break;
                }

                if(j== temperatures.size() - 1 && index ==0)
                    result.push_back(index);
            }
        }
        
        result.push_back(0);
        return result;
    }
};

方法二:单调栈

用空间换时间,相当于把第二个for循环用一个栈去替代了
什么时候用到单调栈?
答:寻找一个数右边(左边)比它大(小)的第一个数
单调栈的作用
答:可以把当前遍历的数的前面所有的数记录下来
具体过程
代码随想录

代码
class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int>result(temperatures.size(), 0);
        stack<int>st;   // 单调栈
        st.push(0);

        for(int i = 1; i < temperatures.size(); i++)
        {
            if(temperatures[i] <= temperatures[st.top()])
                st.push(i);
            else
            {
                while(!st.empty() && temperatures[i] > temperatures[st.top()])
                {
                    result[st.top()] = i - st.top();
                    st.pop();
                }
                st.push(i);
            }
        }

        return result;
    }
};

总结

开始学习单调栈的内容


LeetCode 496 下一个更大元素 I

题目链接:https://leetcode.cn/problems/next-greater-element-i/

思路:

方法一:暴力解法

三个for循环,一个遍历nums1数组,一个遍历nums2数组找到和当前nums1数组相同值的下标,最后一个循环是从找到相同值的下标+1开始往后找第一个比当前值大的值

代码:
class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int>result(nums1.size(), -1);

        for(int i = 0; i < nums1.size(); i++)
        {
            for(int j = 0; j < nums2.size(); j++)
            {
                if(nums1[i] == nums2[j])
                {
                    for(int tmp = j + 1; tmp < nums2.size(); tmp++)
                    {
                        if(nums2[tmp] > nums2[j])
                        {
                            result[i] = nums2[tmp];
                            break;
                        }
                    }
                }
            }
        }

        return result;
    }
};

方法二:单调栈

本题关键点:

  1. result数组的大小
    答:因为题目说了,nums1的数在nums2中均可以找到,所以显然result数组的大小为nums1.size()
  2. 要懂得如何在nums2数组中找出和nums1数组相同的值
    答:题目中说了是两个没有重复元素的数组nums1和nums2。没有重复元素,我们就可以用map来做映射了。根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过
  3. 单调栈的遍历是遍历哪个数组
    答:因为是要在nums2中找比当前值更大的数,所以显然是遍历nums2数组
代码
class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        unordered_map<int,int>map;
        vector<int>result(nums1.size(), -1);
        if(nums1.size() == 1)   return result;
        stack<int>st;
        st.push(0);

        // 将数组1的值和对应下标存进去map中,这样后续在nums2中用单调栈时有判断的条件
        for(int i = 0; i < nums1.size(); i++)
            map[nums1[i]] = i;

        // 因为要找的是数组2中对应元素右边更大的元素,所以遍历数组2
        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()])
                {
                	// 判断当前值是否是在数组1里的
                    if(map.find(nums2[st.top()]) != map.end())
                        result[map[nums2[st.top()]]] = nums2[i];
                    st.pop();
                }
                st.push(i);
            }
        }

        return result;
    }
};

总结

多了一个数组,题目就变得绕了。没有想到用map去做映射,看到之后茅塞顿开。


今日总结:

开始单调栈内容的学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值