代码随想录算法训练营第 49 天 |LeetCode42 接雨水 LeetCode84 柱状图中最大面积矩形

代码随想录算法训练营

Day49 代码随想录算法训练营第 49 天 |LeetCode42 接雨水 LeetCode84 柱状图中最大面积矩形



前言

LeetCode42 接雨水

讲解文档

LeetCode84 柱状图中最大面积矩形

讲解文档


一、LeetCode42 接雨水

1.题目链接

LeetCode42 接雨水

2.思路

(1)寻找元素height[i]前后第一个大于它的元素,左边第一个大于height[i]的元素记作height[left] ,右边第一个大于height[i]的元素记作height[right],[left+1,right-1]区间内,height[i]为最大高度
和原来的相比,增加了[left+1,right-1]区间内,最小高度差的雨水,即
(min(height[right],height[left])-height[mid])*(right-left-1)
(2)单调栈
1)下标0入
2)height[i]小于等于栈顶元素,入栈
3)循环:栈不空,且height[i]小于栈顶元素

  • 栈顶下标记作mid(因为栈顶元素在中间)
  • 弹出
  • 如果空:mid左边没有比他大的,所以跳过
  • 如果不空:
    • 现在的栈顶,原本的栈顶之下第一个元素是左边第一个大于height[mid]的元素
    • 当前增加了[s.top()+1,i-1]区间内,最小高度差的雨水
      res +=(min(height[s.top()], height[i]) - height[mid])*(i - s.top() - 1)

3.题解

class Solution {
public:
    stack<int> s;
    int trap(vector<int>& height) {
        int res = 0;
        s.push(0);
        int n = height.size();
        for (int i = 1; i < n; i++) {

            if (height[s.top()] > height[i]) {
                s.push(i);

            } else if(height[s.top()] ==height[i])
            {
                s.pop();
                s.push(i);
            }
            else {
                while (!s.empty() && height[s.top()] < height[i]) {
                    int mid = s.top();
                    s.pop();
                    if (!s.empty()) {
                        int h = min(height[s.top()], height[i]) - height[mid];
                        int w = i - s.top() - 1;
                        res += w * h;
                        
                    }
                }
                s.push(i);
            }
        }
        return res;
    }
};

二、LeetCode84 柱状图中最大面积矩形

1.题目链接

LeetCode84 柱状图中最大面积矩形

2.思路

(1)寻找元素height[i]前后第一个小于它的元素,左边第一个小于height[i]的元素记作height[left] ,右边第一个小于height[i]的元素记作height[right]
[left+1,right-1]区间内,height[i]为最大高度
当前矩形面积为[left+1,right-1]区间内,高为height[i]的矩形面积
(2)单调栈
1)下标0入
2)height[i]大于等于栈顶元素,入栈
3)循环:栈不空,且height[i]小于栈顶元素

  • 栈顶下标记作mid(因为栈顶元素在中间)
  • 弹出
  • 如果空:当前矩形面积为[mid,i-1]区间内,高为height[mid]的矩形面积
    当次结果为(i-mid)*height[mid]
  • 如果不空:
    • 现在的栈顶,原本的栈顶之下第一个元素是左边第一个小于height[mid]的元素
    • 当前矩形面积为[s.top()+1,i-1]区间内,高为height[mid]的矩形面积
      当次结果为(i-s.top()-1)*height[mid]

3.题解

class Solution {
public:
    stack<int> s;
    int largestRectangleArea(vector<int>& heights) {
        int res = 0;
        heights.insert(heights.begin(), 0); // 数组头部加入元素0
        heights.push_back(0);               // 数组尾部加入元素0
        int n = heights.size();
        s.push(0);
        for (int i = 1; i < n; i++) {
            if (heights[s.top()] <= heights[i]) {
                s.push(i);
            } else {
                while (!s.empty() && heights[s.top()] > heights[i]) {
                    int mid = s.top();
                    s.pop();
                    if (s.empty()) {
                        res = max(res, heights[mid] * (i - mid));
                    } else {

                        res = max(res, heights[mid] * (i - s.top() - 1));
                    }
                }
                s.push(i);
            }
        }
        return res;
    }
};

总结

单调栈用于解决寻找元素左右第一个大于或小于它的元素位置的问题
单调栈里面存放的元素都是待处理的元素

  • 19
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第二十二算法训练营主要涵盖了Leetcode题目的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 下来是Leetcode 977题,题目要求对给定的有序数组的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组找到长度最小的子数组,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值