单调栈part2 | ● 503.下一个更大元素II ● 42. 接雨水

这篇具有很好参考价值的文章主要介绍了单调栈part2 | ● 503.下一个更大元素II ● 42. 接雨水。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


503.下一个更大元素II

思路

本篇我侧重与说一说,如何处理循环数组。

相信不少同学看到这道题,就想那我直接把两个数组拼接在一起,然后使用单调栈求下一个最大值不就行了!

确实可以!

将两个nums数组拼接在一起,使用单调栈计算出每一个元素的下一个最大值,最后再把结果集即result数组resize到原数组大小就可以了。

这种写法确实比较直观,但做了很多无用操作,例如修改了nums数组,而且最后还要把result数组resize回去。

resize倒是不费时间,是O(1)的操作,但扩充nums数组相当于多了一个O(n)的操作。

其实也可以不扩充nums,而是在遍历的过程中模拟走了两边nums。

思路代码

func nextGreaterElements(nums []int) []int {
    res:=make([]int,len(nums))
    for i:=range res{
        res[i]=-1
    }
    stack:=[]int{}
    nums2:=append(nums,nums...)
    for i,v:=range nums2{
        for len(stack)>0&&v>nums2[stack[len(stack)-1]]{
            if stack[len(stack)-1]<len(nums){
                res[stack[len(stack)-1]]=v
            }
            stack=stack[:len(stack)-1]
        }
        stack=append(stack,i)
    }
    return res
}

官方代码

func nextGreaterElements(nums []int) []int {
    length := len(nums)
    result := make([]int,length,length)
    for i:=0;i<len(result);i++{
        result[i] = -1
    }
    //单调递减,存储数组下标索引
    stack := make([]int,0)
    for i:=0;i<length*2;i++{
        for len(stack)>0&&nums[i%length]>nums[stack[len(stack)-1]]{
            index := stack[len(stack)-1]
            stack = stack[:len(stack)-1] // pop
            result[index] = nums[i%length]
        }
        stack = append(stack,i%length)
    }
    return result
}

42. 接雨水

思路

如果当前遍历的元素(柱子)高度大于栈顶元素的高度,此时就出现凹槽了

取栈顶元素,将栈顶元素弹出,这个就是凹槽的底部,也就是中间位置,下标记为mid,对应的高度为height[mid](就是图中的高度1)。

此时的栈顶元素st.top(),就是凹槽的左边位置,下标为st.top(),对应的高度为height[st.top()](就是图中的高度2)。

当前遍历的元素i,就是凹槽右边的位置,下标为i,对应的高度为height[i](就是图中的高度3)。

此时大家应该可以发现其实就是栈顶和栈顶的下一个元素以及要入栈的元素,三个元素来接水!

那么雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度,代码为:int h = min(height[st.top()], height[i]) - height[mid];

雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度),代码为:int w = i - st.top() - 1 ;

当前凹槽雨水的体积就是:h * w。

求当前凹槽雨水的体积代码如下:

while (!st.empty() && height[i] > height[st.top()]) { // 注意这里是while,持续跟新栈顶元素
int mid = st.top();
st.pop();
if (!st.empty()) {
int h = min(height[st.top()], height[i]) - height[mid];
int w = i - st.top() - 1; // 注意减一,只求中间宽度
sum += h * w;
}
}

思路代码

func trap(height []int) int {
    stack:=[]int{}
    res:=0
    for i:=0;i<len(height);i++{
        for len(stack)>0&&height[i]>height[stack[len(stack)-1]]{
            mid:=stack[len(stack)-1]
            stack=stack[:len(stack)-1]
            if len(stack)>0{
                h:=min(height[stack[len(stack)-1]],height[i])-height[mid]
                w:=i-stack[len(stack)-1]-1
                res+=h*w
            }
        }
        stack=append(stack,i)
    }
    return res
}

func min(i,j int)int{
    if i<j{
        return i
    }
    return j
}

困难

凹槽的计算是需要比较左右两侧最小值的,宽度通过下标计算。


今日收获

接雨水问题,凹槽用单调栈计算。文章来源地址https://www.toymoban.com/news/detail-539128.html

到了这里,关于单调栈part2 | ● 503.下一个更大元素II ● 42. 接雨水的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【算法练习Day50】下一个更大元素II&&接雨水

    ​📝个人主页:@Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯 长路漫漫浩浩,万事皆有期待 503. 下一个更大元素 II - 力扣(LeetCode) 给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更

    2024年01月22日
    浏览(35)
  • 算法刷题Day 59 下一个更大元素II+接雨水

    其实也可以不扩充nums,而是在遍历的过程中模拟走了两边nums 三种方法都写了一遍 暴力方法 逐列计算 找到当前位置,左边最高的柱子的索引和右边最高的柱子的索引,两者中相对小的那个,将去当前位置的高度,就是水柱的高度,而宽度是1 超时了 双指针 提前记录好左边最

    2024年02月14日
    浏览(38)
  • leetcode496. 下一个更大元素 I 【单调栈】

    【简单题】(暴力遍历法很简单)但是时间复杂度很高,n的立方级别了。。。 代码: 运行结果:   进阶方法: 进阶: 你可以设计一个时间复杂度为  O(nums1.length + nums2.length)  的解决方案吗? 答案思路:【单调栈】 怎么样才能使得 用 nums1中的元素去 nums2中查找的时候,能

    2024年02月10日
    浏览(42)
  • 【力扣】496. 下一个更大元素 I <单调栈、模拟>

      nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。给你两个没有重复元素的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。   对于每个 0 = i nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定

    2024年02月12日
    浏览(37)
  • 【单调栈】【二分查找】LeetCode: 2454.下一个更大元素 IV

    【动态规划】【广度优先】LeetCode2258:逃离火灾 单调栈分类、封装和总结 二分查找算法合集 给你一个下标从 0 开始的非负整数数组 nums 。对于 nums 中每一个整数,你必须找到对应元素的 第二大 整数。 如果 nums[j] 满足以下条件,那么我们称它为 nums[i] 的 第二大 整数: j i n

    2024年02月03日
    浏览(42)
  • (单调栈) 496. 下一个更大元素 I——【Leetcode每日一题】

    难度:简单 nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x 大的元素。 给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中 nums1 是 nums2 的子集。 对于每个 0 = i nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums

    2024年02月08日
    浏览(40)
  • LeetCode42.接雨水(单调栈)

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 思路: 从题目中我们可以知道:只有凹陷的地方才可以存储雨水,那么高度一定是先减后增,所以当我们遍历到 增 这个位置时,前面减的地方(即凹陷的地方)一定会存储

    2024年02月21日
    浏览(33)
  • LeetCode-42. 接雨水【栈 数组 双指针 动态规划 单调栈】

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

    2024年02月04日
    浏览(39)
  • LeetCode每日一题 1019. 链表中的下一个更大节点 --单调栈

      Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接       我会一直往里填充内容哒! 🌈LeetCode专栏:专栏链接       目前在刷初级算法的LeetBook 。若每日一题当中有力所能

    2024年02月01日
    浏览(60)
  • leetcode 496. 下一个更大元素 I

             这题提供暴力解法和单调栈法两种方法。         题中说了数组中没有重复的元素,为了避免重复遍历nums2数组,可以用一个哈希map和单调栈stack将nums2数组中的每个元素对应其查询值存储在map中,类似于每日温度。然后再遍历nums1查询相应元素对应的查询值。 代码

    2024年02月11日
    浏览(41)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包