前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >接雨水 & 最大点

接雨水 & 最大点

作者头像
羽翰尘
发布于 2020-07-14 03:14:12
发布于 2020-07-14 03:14:12
37200
代码可运行
举报
文章被收录于专栏:技术向技术向
运行总次数:0
代码可运行

问题一: 盛最多水的容器

leetcode题号:11

题目

给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入:[1,8,6,2,5,4,8,3,7]
输出:49

解答

左右两个指针,比较矮的一堵墙向中间走,一直走到两个指针相遇。

最基础的解法当然是选择两个当容器,复杂度为O(n^2), 这种解法显著降低了复杂度。为什么非要是较低的指针向中间走呢?难道不害怕错过解空间?

实际上,area = min(height[l], height[r]) * (r - l), 较大值向中间走后,(r - l)是一定减小的,设走之后遇到的值为height[m](这里假设l与r不动), 如果height[m] > min(height[l], height[r]),计算面积时还是采用min(height[l], height[r]),并不会增加。所以面积是一定减小的。

所以该问题可以归类为解空间的优化,从O(n^2)降为O(n), 依赖观察与计算。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int maxArea(vector<int>& height) {
        int res = 0;
        for(int i = 0, j = height.size() - 1; i < j;){
            res = max(res, (j - i) * min(height[i], height[j]));
            height[i] < height[j] ? i++ : j--;
        }
        return res;
    }
};

问题二:接雨水

leetcode题号:42

题目

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

解答

虽说有人将这种方法称为双向dp,但我觉得不妥。归结为记录扫描过程中的最大值最好

仔细观察题目中的图片,一定会有最高值,然后雨水在中间的凹陷处。那么我们从左侧开始扫描,只记录最大值;从右侧开始扫描,同样只记录最大值。然后取两个最大值中的较小者作为dp值。这时候dp值减去当前值就是所接的雨水。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int trap(vector<int>& height) {
        if(height.size() == 0) return 0;
        vector<int> dp(height.size());
        int left_max = height[0];
        int right_max = height[height.size() - 1];
        for(int i = 0; i < dp.size(); i++){
            left_max = max(left_max, height[i]);
            dp[i] = left_max;
        }
        for(int i = (int)dp.size() - 1; i >= 0; i--){
            right_max = max(right_max, height[i]);
            dp[i] = min(right_max, dp[i]);
        }
        int res = 0;
        for(int i = 0; i < dp.size(); i++){
            res += dp[i] - height[i];
        }
        return res;
    }
};

问题三:二维点集中的最大点

题目

P为给定的二维平面整数点集。定义 P 中某点x,如果x满足 P 中任意点都不在 x 的右上方区域内(横纵坐标都大于x),则称其为“最大的”。求出所有“最大的”点的集合。(所有点的横坐标和纵坐标都不重复, 坐标轴范围在[0, 1e9) 内)

如下图:实心点为满足条件的点的集合。请实现代码找到集合 P 中的所有 ”最大“ 点的集合并输出。

解答

对于所有的点先按照y从大到小排序O(NlongN) 从大到小遍历排好序的点集,当前y是出现过的最大的y,即是需要的结果,进行输出O(N)。 总体时间复杂度为O(NlogN)

还可以这样理解,从y轴向下走,记录x值的最大值。如果有点打破了x值记录,就纳入最大点的结合。还是一种边走边记录最大值的方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);//提升cin和cout的性能
    int n_pointer=0;
    cin>>n_pointer;
    vector<pair<int,int>> xys;
    for(int i=0;i<n_pointer;i++)
    {
        int x,y;
        cin>>x>>y;
        xys.push_back(make_pair(x,y));
    }
     
    sort(xys.begin(),xys.end(),[](pair<int,int> &p1,pair<int,int> &p2)->bool{
        return p1.second>p2.second;
    });
     
    int max_x=-1;
 
    for(auto &pair:xys)
    {
        if(pair.first>max_x)
        {
            cout<<pair.first<<" "<<pair.second<<endl;
            max_x=pair.first;
        }
    }
     
    return 0;
}

对比分析

问题二与问题三都是边走边记录最大值的方法,适合于和图形相关的包裹、边界问题。

问题一与问题二外观相似,但是核心不同。问题二的纵坐标是有宽度的,会影响蓄水。

后续还有接雨水2,以及其他的相似题目待解答分析。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
LeetCode 0042 - Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
Reck Zhang
2021/08/11
2410
【leetcode刷题】T31-接雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
木又AI帮
2019/07/17
5010
【leetcode刷题】T31-接雨水
​LeetCode刷题实战42:接雨水
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
程序员小猿
2021/01/20
2580
​LeetCode刷题实战42:接雨水
42. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
chuckQu
2022/08/19
2780
【奇技淫巧】-- 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
看、未来
2020/08/25
3790
【奇技淫巧】-- 接雨水
算法:动态规划(DP)入门实践
入门 在知乎上看到徐凯强 Andy的答案后感觉入门了 实践 题目:仅包含0/1的矩阵,求其中最大的全1方阵(不能是矩形)的边长 题解:matrxi[100][100]表示0/1矩阵,dp[i][j]表示:以matrix[i][j]为右下角,边长最大为min(i,j)的,最大全1方阵的边长, if(matrix[i][j]==0) { dp[i][j]=0; } if(matrix[i][j]==1) { if(dp[i-1][j]==1&&dp[i][j-1]==1) { dp[i
keloli
2018/09/13
9220
L_00042_Trap:左右填充解接雨水问题
https://leetcode-cn.com/problems/trapping-rain-water/ 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
mingjie
2022/05/12
2240
L_00042_Trap:左右填充解接雨水问题
LeetCode 42. 接雨水(双指针、单调栈)
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
Michael阿明
2020/07/13
1.1K0
LeetCode 42. 接雨水(双指针、单调栈)
[Leetcode][python]Trapping Rain Water/接雨水
参考:http://www.cnblogs.com/zuoyuan/p/3781453.html
蛮三刀酱
2019/03/26
6740
【Leetcode】接雨水(双指针、单调栈)
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
P_M_P
2024/01/22
1810
【Leetcode】接雨水(双指针、单调栈)
【LeetCode热题100】【双指针】接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
叶茂林
2023/12/06
1640
【LeetCode热题100】【双指针】接雨水
Leetcode 42题 接雨水(Trapping Rain Water)
https://leetcode-cn.com/problems/trapping-rain-water/
code随笔
2020/06/16
4600
数组矩阵杂题
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
王脸小
2019/10/30
6920
【LeetCode】42. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
韩旭051
2020/06/23
3440
【LeetCode】42. 接雨水
LeetCode 0042. 接雨水[动态规划详解]
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
Yano_nankai
2021/03/02
6160
LeetCode 0042. 接雨水[动态规划详解]
leetcode 接雨水2_code42
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
全栈程序员站长
2022/09/22
1520
每日两题 T15
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
合一大师
2020/07/20
3060
每日两题 T15
程序员进阶之算法练习(八十九)leetcode
题目链接 题目大意: 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
落影
2023/11/02
1990
程序员进阶之算法练习(八十九)leetcode
常见编程模式之双指针
双指针模式指使用两个一前一后的指针遍历数据结构,直到某个指针触发停止条件。该模式常用于在有序数组或链表中搜索元素对。使用双指针的好处在于和单指针相比,不用去连续遍历整个数组来找出答案,可以带来更好的时间或空间复杂度。
口仆
2020/08/14
2K0
【刷穿 LeetCode】42. 接雨水(困难)
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
宫水三叶的刷题日记
2021/02/20
5820
相关推荐
LeetCode 0042 - Trapping Rain Water
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档