首页 > 编程语言 >代码随想录算法训练营第 48 天 |LeetCode 739. 每日温度 LeetCode496.下一个更大元素 I LeetCode503.下一个更大元素II

代码随想录算法训练营第 48 天 |LeetCode 739. 每日温度 LeetCode496.下一个更大元素 I LeetCode503.下一个更大元素II

时间:2024-08-23 15:26:42浏览次数:14  
标签:栈顶 top 元素 随想录 vector 更大 nums1 nums2

代码随想录算法训练营

Day48 代码随想录算法训练营第 48 天 |LeetCode 739. 每日温度 LeetCode496.下一个更大元素 I LeetCode503.下一个更大元素II


目录


前言

LeetCode 739. 每日温度

讲解文档

LeetCode496.下一个更大元素 I

讲解文档

LeetCode503.下一个更大元素II

讲解文档


一、基础

1、栈内存放下标

2、应用:找元素右边第一个大于/小于他的元素

3、找元素右边第一个大于他的元素

(1)a[0]:将0放入栈
(2)a[i]:
1)如果栈空:i入栈
2)如果栈顶对应元素大于等于a[i]:i入栈
3)栈顶对应元素小于a[i]:(while循环控制边界)
① a[i]就是栈顶对应元素右边第一个大于他的元素,记录答案
② 弹出栈顶
③ i入栈

二、LeetCode 739. 每日温度

1.题目链接

LeetCode 739. 每日温度

2.思路

1)a[0]:将0放入栈
(2)a[i]:
1)如果栈空:i入栈
2)如果栈顶对应元素大于等于a[i]:i入栈
3)栈顶对应元素小于a[i]:(while循环控制边界)
① a[i]就是栈顶对应元素右边第一个大于他的元素,记录答案---- i-s.top()
② 弹出栈顶
③ i入栈

3.题解

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

三、LeetCode496.下一个更大元素

1.题目链接

LeetCode496.下一个更大元素

2.思路

问题转换:
问题转换成:同时属于nums1和nums2的元素在nums2中右边第一个比自己大的元素下标
方法一:
(1)单调栈存放待处理的元素下标:
单调栈存放nums2的元素在Nums2中下标(但是真正对答案有用的是同时属于nums1和nums2的元素)
(2)过程
1)为了通过同时属于nums1和nums2的元素值找在nums1中的下标,用映射,元素为key,下标为values
2)单调栈
① 下标0放入
② 栈空或栈顶元素>=nums2[i]:入栈
③ 栈顶元素<nums2[i]:
如果栈顶元素在nums1出现,那么栈顶元素在nums1中对应元素的答案是nums2[i]
无论栈顶元素是否在nums1出现,弹出栈顶
跳出循环后i入栈
方法二:
1)单调栈存放待处理的元素下标:
单调栈存放同时属于nums1和nums2的元素在Nums2中下标
(2)过程
1)为了通过同时属于nums1和nums2的元素值找在nums1中的下标,用映射,元素为key,下标为values
2)单调栈
① 栈空或栈顶元素>=nums2[i]:如果nums2[i]在nums1出现,i入栈
③ 栈顶元素<nums2[i]:
栈顶元素在nums1中对应元素的答案是nums2[i]
弹出栈顶
跳出循环后,如果nums2[i]在nums1出现,i入栈

3.题解

方法1

class Solution {
public:
stack<int>s;
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int n1=nums1.size();
        int n2=nums2.size();
        vector<int>res(n1,-1);
        s.push(0);
        unordered_map<int,int>map;
        for(int i=0;i<n1;i++){
            map[nums1[i]]=i;
        }
        for(int i=1;i<n2;i++)
        {
            if(s.size()==0 || nums2[s.top()]>=nums2[i])s.push(i);
            else
            {
                while(!s.empty()&&nums2[s.top()]<nums2[i])
                {
                    if(map.count(nums2[s.top()]) > 0)
                        res[map[nums2[s.top()]]]=nums2[i];
                    s.pop();
                }
                
                s.push(i);
            }

        }
        return res;
    }
};

方法2

class Solution {
public:
    stack<int> s;
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int n1 = nums1.size();
        int n2 = nums2.size();
        vector<int> res(n1, -1);

        unordered_map<int, int> map;
        for (int i = 0; i < n1; i++) {
            map[nums1[i]] = i;
        }
        for (int i = 0; i < n2; i++) {
            if ((s.size() == 0 || nums2[s.top()] >= nums2[i]) &&
                map.count(nums2[i]) > 0) {
                s.push(i);

            } else {
                while (!s.empty() && nums2[s.top()] < nums2[i]) {

                    res[map[nums2[s.top()]]] = nums2[i];
                    s.pop();
                }

                if (map.count(nums2[i]) > 0)
                    s.push(i);
            }
        }
        return res;
    }
};

四、LeetCode503.下一个更大元素II

1.题目链接

LeetCode503.下一个更大元素II

2.思路

(1)审题:循环数组

e.g.输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数; 
第二个 1 的下一个最大的数需要循环搜索,结果也是 2

(2)为了确保每个元素都能搜索完一个周期:从0到2n-1遍历
(相当于将数组扩增:abd—abdabd)

3.题解

class Solution {
public:
    stack<int> s;
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = nums.size();
        vector<int> res(n, -1);

        for (int i = 0; i < n * 2; i++) {
            if (s.empty() || nums[s.top()] >= nums[i % n])
                s.push(i % n);
            else {
                while (!s.empty() && nums[s.top()] < nums[i % n]) {
                    res[s.top()] = nums[i % n];
                    s.pop();
                }
                s.push(i % n);
            }
        }
        return res;
    }
};

标签:栈顶,top,元素,随想录,vector,更大,nums1,nums2
From: https://blog.csdn.net/2301_79647020/article/details/141337562

相关文章

  • 代码随想录day 38 || 322 零钱兑换,279 完全平方数,139 单词拆分
    322零钱找还funccoinChange(coins[]int,amountint)int{ //装满,并且硬币无限,可以类比完全背包问题 //dp[i][j]表示前i个物品装满容量为j的背包所需要的最少物品数量 //递推公式dp[i][j]=min(dp[i-1][j],dp[i][j-w(i)]+1)//不装物品i的物品数量,装物品i的物品数......
  • 力扣: 移除链表元素
    文章目录需求虚拟头结点法原头结点法结尾需求给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val==val的节点,并返回新的头节点。示例1:输入:head=[1,2,6,3,4,5,6],val=6输出:[1,2,3,4,5]示例2:输入:head=[],val=1输......
  • 存在重复元素 II(LeetCode)
    题目        给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i]==nums[j] 且 abs(i-j)<=k 。如果存在,返回 true ;否则,返回 false 。解题"""时间复杂度为O(n),空间复杂度为O(min(n,k)),其中n......
  • 代码随想录DAY22 - 回溯算法 - 08/21
    目录理论回顾什么是回溯法回溯法的效率回溯法解决的问题如何理解回溯组合题干思路和代码递归法递归优化:剪枝组合总和Ⅲ题干思路和代码递归法递归优化电话号码的字母组合题干思路和代码递归法理论回顾什么是回溯法回溯是一种类似枚举的搜索方法,回溯和......
  • 代码随想录DAY23 - 回溯算法 - 08/22
    组合总和题干题目:给你一个无重复元素的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target的所有不同组合,并以列表形式返回。你可以按任意顺序返回这些组合。candidates中的同一个数字可以无限制重复被选取。如果至少......
  • 代码随想录算法训练营第二十三天(回溯 二)
    力扣题部分:39.组合总和题目链接:.-力扣(LeetCode)题面:给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。candid......
  • 代码随想录算法训练营第二十二天(回溯 一)
    开始学习回溯!回溯理论基础代码随想录文章链接:代码随想录文章摘要:什么是回溯法回溯法也可以叫做回溯搜索法,它是一种搜索的方式。在二叉树系列中,我们已经不止一次,提到了回溯。回溯是递归的副产品,只要有递归就会有回溯。所以以下讲解中,回溯函数也就是递归函数,指的都是一......
  • 代码随想录Day23
    131.分割回文串给你一个字符串s,请你将s分割成一些子串,使每个子串都是回文串。返回s所有可能的分割方案。示例1:输入:s="aab"输出:[["a","a","b"],["aa","b"]]示例2:输入:s="a"输出:[["a"]]提示:1<=s.length<=16s仅由......
  • 「代码随想录算法训练营」第四十四天 | 图论 part2
    200.岛屿数量题目链接:https://leetcode.cn/problems/number-of-islands/description/文章讲解:https://programmercarl.com/kamacoder/0099.岛屿的数量深搜.html题目难度:中等题目状态:看题解思路一:深搜版方法dfs:参数:接受一个字符网格grid和当前坐标(r,c)。功能:......
  • 给自己复盘的随想录笔记-移除元素
    双指针法双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。定义快慢指针快指针:寻找新数组的元素,新数组就是不含有目标元素的数组慢指针:指向更新新数组下标的位置相关题目删除有序数组中的重复项解题思路:解法:双指针首先注意数组......