代码随想录训练营Day 62|力扣739. 每日温度、496.下一个更大元素 I、503.下一个更大元素II

1.每日温度

代码:(单调栈)

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        stack<int> st;
        vector<int> result(temperatures.size(),0);
        // 找不到下一个最高温度的天用0来代替
        st.push(0);
        // 单调栈里放的是下标,为了正确计算天数差。而且访问元素也方便
        for(int i = 1; i < temperatures.size(); i++){
            if(temperatures[i] < temperatures[st.top()]){
                st.push(i);
            }else 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;
    }
};

思路:

感觉这个单调栈的玩法有种消消乐的感觉(?

保证单调栈里的元素都是单调递增的,如果遇到一个比栈顶元素大的数据,就去消消乐,消到只剩比它大的元素。

易错点:消消乐的过程要用循环!!消完所有可以抵消的再将当前遍历元素入栈。

2.下一个更大元素

代码:(单调栈)

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        stack<int> st;
        vector<int> result(nums1.size(),-1); // 不存在下一个更大元素返回-1
        unordered_map<int,int> umap;
        for(int i = 0; i < nums1.size(); i++){ // 建立nums1元素数值到下标的映射 后续用这种映射来找下标 然后填result数组
            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 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){ // 找umap里有没有这个元素(因为我们只要求nums2的子集即可,也就是nums1里的元素对应的result数组)
                        result[umap[nums2[st.top()]]] = nums2[i];
                    }
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;
    }
};

 思路:

这道题的难点就是要搞清楚result是填哪个数组(nums1)元素的对应值,入栈要求下一个最大元素的是哪个数组(nums2)。

因为题上说nums1是nums2的子集,而且数组元素而不相同,那么我们是可以通过元素值唯一对应到该元素值的下标的。也就是我们可以通过nums2的元素值(nums1是nums2的子集)来找到nums1对应元素的下标。

那么这种元素—下标的映射,就用unorder_map来记录。

和上一题一样,将nums2里的元素依次和栈顶元素作比较,进行对应的操作。如果遇到了栈不为空且当前元素比栈顶元素大的情况,就去看看nums1里有没有这个元素(看umap里有没有记录这个映射关系),如果有,就找到nums1的对应下标,将result里的相同下标的元素值赋值为当前nums2里遍历到的元素值。

易错点:将栈顶元素出栈的操作应该在if语句外,因为不管nums1里有没有这个元素,都要进行消消乐,满足单调栈的定义。将当前遍历的元素入栈,应该放在消消乐循环的外面,确保所有比它小的元素都被处理完了。

3.下一个更大元素2

 代码随想录

代码:  (单调栈)

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        stack<int> st;
        vector<int> result(nums.size(),-1);
        st.push(0);
        for(int i = 1; i < 2 * nums.size(); i++){
            if(nums[i % nums.size()] <= nums[st.top()]){
                st.push(i % nums.size());
            }else{
                while(!st.empty() && nums[i % nums.size()] > nums[st.top()]){
                    result[st.top()] = nums[i % nums.size()];
                    st.pop();
                }
                st.push(i % nums.size());
            }
        }
        return result;
    }
};

思路:

和每日温度的区别就是这里要求得是循环数组。

有两种办法,一个是把原数组复制一份拼上去。

一种是模拟遍历了两次数组,

模拟遍历两边nums,注意一下都是用i % nums.size()来操作
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值