首页 > 编程语言 >代码随想录算法训练营第四十八天|Day48 单调栈

代码随想录算法训练营第四十八天|Day48 单调栈

时间:2024-11-16 21:16:34浏览次数:3  
标签:int top ans 随想录 直方图 Day48 第四十八 stack maxArea

42. 接雨水

https://programmercarl.com/0042.%E6%8E%A5%E9%9B%A8%E6%B0%B4.html

思路

int trap(int* height, int heightSize) {
    int ans = 0;
    int left = 0, right = heightSize - 1;              
    int leftMax = 0, rightMax = 0;                     
    while (left < right) {                             
        leftMax = fmax(leftMax, height[left]);
        rightMax = fmax(rightMax, height[right]);
        if (leftMax < rightMax) {
            ans += leftMax - height[left];              
            ++left;
        }
        else {
            ans += rightMax - height[right];           
            --right;
        }
    }
    return ans;
}

学习反思

用来计算雨水收集的总量的。它使用了双指针的方法来遍历数组,并计算左侧和右侧的最大高度。在遍历的过程中,根据左右两侧的最大高度来确定当前位置可以收集的雨水量。代码的思路比较清晰,先定义了结果变量 ans,并初始化左右指针 left 和 right。同时,定义了左右两侧的最大高度变量 leftMax 和 rightMax。然后使用 while 循环,当左指针小于右指针时,进行遍历。在遍历的过程中,使用 fmax 函数更新左右两侧的最大高度。然后,根据左右两侧的最大高度来判断当前位置可以收集的雨水量。如果左侧最大高度小于右侧最大高度,则更新 ans,并将左指针右移。否则,更新 ans,并将右指针左移。最后,返回 ans 作为结果。整体来说,这段代码使用了双指针的方法,时间复杂度为 O(n),空间复杂度为 O(1)。

柱状图中最大的矩形

https://programmercarl.com/0084.%E6%9F%B1%E7%8A%B6%E5%9B%BE%E4%B8%AD%E6%9C%80%E5%A4%A7%E7%9A%84%E7%9F%A9%E5%BD%A2.html

思路

int largestRectangleArea(int* heights, int heightsSize) {
    int* stack = (int*)malloc(heightsSize * sizeof(int));
    int top = -1; 
    int maxArea = 0; 
    int i;
    for (i = 0; i < heightsSize; i++) {
        while (top != -1 && heights[i] < heights[stack[top]]) {
            int h = heights[stack[top--]]; 
            int width = (top == -1) ? i : (i - stack[top] - 1); 
            maxArea = maxArea > h * width ? maxArea : h * width; 
        }
        stack[++top] = i; 
    }
    while (top != -1) {
        int h = heights[stack[top--]]; 
        int width = (top == -1) ? i : (i - stack[top] - 1); 
        maxArea = maxArea > h * width ? maxArea : h * width;
    }
    free(stack);
    return maxArea; 
}

学习反思

使用栈来记录直方图的索引。遍历直方图数组,如果当前直方图高度小于栈顶直方图高度,则栈顶直方图所形成的矩形面积可以计算出来了。计算方法是以栈顶直方图为高,栈顶索引与当前索引之间的宽度为宽。计算完后,将栈顶元素出栈继续计算,直到栈为空或者当前直方图高度大于栈顶直方图高度。将当前索引入栈。遍历结束后,栈中可能还存在一些直方图,这是因为这些直方图的右边界还未遍历到,所以可以将这些直方图按照右边界为数组长度的方式计算矩形面积。最后返回计算得到的最大矩形面积。该算法的时间复杂度是O(n),空间复杂度是O(n)。

总结

加油!!!

标签:int,top,ans,随想录,直方图,Day48,第四十八,stack,maxArea
From: https://blog.csdn.net/a6666999d/article/details/143823479

相关文章

  • 代码随想录算法训练营day47| 739. 每日温度 496.下一个更大元素 I 503.下一个
    学习资料:https://programmercarl.com/0739.每日温度.html#算法公开课单调栈:用数组模拟单调栈,今天的题中,栈中元素都保存的索引值基本思路:将新元素和栈顶索引对应值比较,如果要保持单调递增,则需要新元素不大于栈顶索引对应值;若满足就加入新元素索引到栈中;若不满足,就根据具体题意看......
  • 代码随想录算法训练营day46| 647. 回文子串 516.最长回文子序列
    学习资料:https://programmercarl.com/0647.回文子串.html#算法公开课动态规划最后一部分:回文字符串子串是从原字符串中连续截取的;子序列可以是从原字符串中不连续提取出元素构成的学习记录:647.回文子串(难构造dp数组,dp数组是从原字符串截取[i,j]范围的片段是否是回文字符串,布尔......
  • 代码随想录:有序数组的平方
    代码随想录:有序数组的平方仍然是双指针,一开始也想到了双指针,不过很笨的创造了两个数组,一个负数的一个正数的,两个数组比大小后插入。但其实可以直接把原数组平方后,从左右两边插入。有两点值得注意:1.已知数组大小的情况下,可以直接倒着插入数组。2.创建vector时需要指定元素的个数......
  • 代码随想录算法训练营第一天| 704. 二分查找、35.搜索插入位置、27. 移除元素、977.有
    文档讲解:代码随想录视频讲解:代码随想录状态:完成4道题一、数组理论基础数组:连续内存空间,存储类型相同的元素集合,适合读不适合写注意:Python里可以存储不同类型的元素,但刷题时都是按照相同元素去做的相同元素占用存储的空间大小是一样的,下一个元素的位置就确定了数组时间......
  • 代码随想录算法训练营第二天| 209.长度最小的子数组、59. 螺旋矩阵 II
    文档讲解:代码随想录视频讲解:代码随想录状态:完成2道题滑动窗口滑动窗口:两个指针一前一后组成滑动窗口,并计算滑动窗口中的元素的问题适用场景:字符串匹配问题、子数组问题、定长问题滑动窗口模板:如果一个字符进入窗口,应该增加windows计数器;如果一个字符将移除窗口的......
  • 代码随想录算法训练营第三十天| 452. 用最少数量的箭引爆气球 、435. 无重叠区间 、76
    452.用最少数量的箭引爆气球思路:以前做过最大不相交子序列的题,这次也是往这根据某一端排序的思路想的,排序后如下图,只需要维护一个公共序列的右边界r就可以了,下一次判断时,只需要判断子区间的左边是否小于r。这个题有点坑的是使用Arrays排序,如果使用昨天的方法:Arra......
  • 代码随想录算法训练营 | 200.岛屿的数量
    岛屿的数量题目链接:https://leetcode.cn/problems/number-of-islands/此题目要点:dfs和bfs都可以解决此题,但是使用dfs代码会更加的简洁首先对grid进行遍历,每一个节点都进行检查,判断是否是1(陆地)如果是,则进行dfs深搜,并将所有搜到的岛屿节点全置为0,表示此块岛屿已经被搜过了,防......
  • 代码随想录算法训练营day45| 115.不同的子序列 583. 两个字符串的删除操作 72.
    学习资料:https://programmercarl.com/0115.不同的子序列.html#算法公开课动态规划系列之编辑距离问题学习记录:115.不同的子序列(当遇到相同字母时,可以选择也可以不选;刚开始没看懂;dp[i][j]是对应i-1结尾和j-1结尾,这样的目的是方便第一行和第一列初始化)点击查看代码classSolut......
  • 代码随想录:二分查找
    代码随想录:二分查找二分法标志:数组顺序排列且无重复简单的二分法,写法是左闭右闭的写法,此种情况的left可以等于right,故while里有等号。classSolution{public:intsearch(vector<int>&nums,inttarget){intleft=0;intright=nums.size()-1;......
  • 代码随想录:移除元素
    代码随想录:移除元素题目中的原地指的是不能开创新的数组。简单双指针解决问题,实际上是vector中的erase的实现原理//erase和迭代器的使用方法std::vector<int>vec={1,2,3,4,5};autoit=vec.begin()+2;//指向元素3//这所谓迭代器其实就是封装后的指针啊vec.era......