代码随想录Day62

这篇具有很好参考价值的文章主要介绍了代码随想录Day62。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今天继续学习单调栈解决相关问题。

496.下一个更大的元素|

nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。

给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。

返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。

示例 1:

输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
示例 2:

输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。

思路:

1.本题在Day61初次接触的那道每日温度的基础之上稍加变化了一下,原本是只有一个数组,我们只需要按部就班找到每一个元素右边第一个比他大的就行,本题则是采用了两个数组并且其中一个数组是另一个数组的子集,让我们找子集数组里面所有元素在另一个数组里面右边的第一个比他大的元素。

2.因为分成了两个无重复元素的数组,因此我们需要建立起两个数组之间的联系。既然无重复元素,可以想到利用哈希表来建立映射,以元素值为键,以下标为值,正好也对应上我们用单调栈存储的是遍历过的元素下标。

3.单调栈中依旧采取从栈头到栈底递增的顺序,这样才能保证找到的是右边第一个更大的元素。

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 i = 0; i < nums1.size(); 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()]){
                    //先判断栈顶元素是否存在于nums1中,如果存在才进行结果存储
                    if(umap.count(nums2[st.top()])){
                        int index = umap[nums2[st.top()]];
                        result[index] = nums2[i];
                    }
                    //判断完栈顶元素后要将栈顶元素出栈
                    st.pop();
                }
                st.push(i);
            }
        }

        return result;
    }
};

启发:

1.本题将单个数组拆成了两个数组,因此我们需要建立起两个数组之间的联系进一步来转化为类似单个数组的解题方法。

503.下一个更大元素||

给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。

数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。

示例 1:

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

输入: nums = [1,2,3,4,3]
输出: [2,3,4,-1,4]

思路:

1.本题同样是在Day61的每日温度基础之上进行了另一种变化,只有一个数组但是数组成环了。既然成环了那么就会很容易想到进行取模的操作来达成环的效果。

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        vector<int> result(nums.size(), -1);
        stack<int> st;

        st.push(0);
        for(int i = 1; i < nums.size() * 2; 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;
    }
};

启发:

1.本题其实细节还是不少的,如在for循环中i的判断条件,尽管成环了理论上来说可以无限次循环整个数组,但实际上只要循环数组的大小*2就足够我们找到所有元素的情况了,后续的循环没有意义。

2.本题中result中的元素是否会被后续成环后的第二次循环覆盖掉呢?其实并不会,实际代入几个结果模拟后就会发现尽管第二轮循环中会将result的值进行“改变”,但实际上对应元素赋的都是同一个值,就好像第一次循环我们找到了每个元素右边第一大的元素,第二轮循环我们只是从头开始又循环了一次,同样会找到每个元素右边第一大的元素(并且这个元素并不会改变)文章来源地址https://www.toymoban.com/news/detail-428617.html

到了这里,关于代码随想录Day62的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 代码随想录day59

    647. 回文子串 给你一个字符串  s  ,请你统计并返回这个字符串中  回文子串  的数目。 回文字符串  是正着读和倒过来读一样的字符串。 子字符串  是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不

    2024年02月07日
    浏览(28)
  • 代码随想录Day50

    昨天因为准备面试所以咕咕了一天。今天继续学习动规算法,尽管背包问题已经结束但其中的各类思想仍需要进一步理解。 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两

    2023年04月14日
    浏览(32)
  • 代码随想录day02

    ● 力扣题目链接 ● 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 思路 ● 暴力排序,时间复杂度O(n + nlogn) ● 使用双指针,时间复杂度O(n) 代码 ● 力扣题目链接 ● 给定一个含有 n 个正整数的数组和一个正整

    2024年02月13日
    浏览(27)
  • 代码随想录day01

    ● 思维不难,主要是考察对代码的掌控能力 ● 内存中的存储方式:存放在连续内存空间上的相同类型数据的集合 ● 数组可以通过下标索引获取到下标对应的数据 ● 数组下标从0开始 ● 因为内存空间地址连续,因此删除或增加元素的时候,难免移动其他元素地址 ● Java中的

    2024年02月13日
    浏览(38)
  • 代码随想录day11

    20. 有效的括号   思路:这里用模拟栈的方法会更好理解,也就是我们每次遇到朝左方向的三种类型的时候,就加入相反方向的右括号到result栈中。由于栈是一个先进后出的方式,所以我们会有一个判断stack当前为不为空,和stack[-1]是不是和当前循环到的括号相同。如果说相同

    2024年02月13日
    浏览(29)
  • 代码随想录day44

    完全背包 其实就是每个物品可以使用无数次,给我们一个容器,装满这个容器的最大价值是多少。 思路: 如果求组合数就是外层for循环遍历物品,内层for遍历背包。 如果求排列数就是外层for遍历背包,内层for循环遍历物品。 完全背包的组合和排序 518. 零钱兑换 II 题目 给你

    2023年04月17日
    浏览(40)
  • 代码随想录Day58

    昨天因为志愿活动和笔试耽误了一整天,今天继续学习动规解决子序列问题。 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,\\\"ace\\\"是\\\"abcde\\\"的一个子序列,

    2023年04月27日
    浏览(35)
  • 【代码随想录】刷题Day31

    455. 分发饼干 贪心的思路就是:小的饼干尽量去匹配胃口小的孩子,这样才能实现尽可能多孩子吃到。 那么代码就很好写了: 1.排序g和s,这样方便查找小的数 2.饼干的位置不停遍历,对应我们需要一个ret代表当前孩子位置 3.如果当前位置为孩子的数量,说明ret记录下所有的

    2024年02月06日
    浏览(25)
  • 【代码随想录】刷题Day41

    343. 整数拆分 1.dp数组的含义:第i个就表示当前i能被拆分出相乘最大的整数 2.那么其实,所谓的后续的i对应的相乘最大整数其实就是前面的相乘最大整数拼凑而成,为了更好的区分我们将分离出来的数为j,那么我们的工作就是将一个又一个的j从i中剥离出,随后相乘即可。那

    2024年02月07日
    浏览(30)
  • 代码随想录day42(背包)

    2024年02月13日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包