LeetCode 热题 100 | 双指针(下)

news2024/11/15 1:59:55

目录

42. 接雨水

1  方法一:我的方法

2  方法二:动态规划

3  方法三:双指针


菜鸟做题第一周,语言是 C++

42. 接雨水

1  方法一:我的方法

Warning:这是我的智障做法,请勿模仿

我只能说它教会了我 “&&” 是从左到右进行判断的,第一个不成立就不会看第二个了。当判断条件顺序写反时,即使我写了防止指针越界的约束条件,它也压根看不到。最后就会这样:

解题思路:

  1. 正向遍历,算每个下标的积水高度(绿色面积)
  2. 反向遍历,算每个下标的积水高度(红色面积)
  3. 取每个下标的积水高度的较小值即为真实积水高度(阴影面积)

力扣官方说明图:

class Solution {
public:
    int trap(vector<int>& height) {
        int left = 0, right = 0, rain = 0;
        unordered_map<int, int> forward, backward;

        // 正向遍历
        while (left <= height.size() - 1) {
            while (right <= height.size() - 1 && height[left] >= height[right])
                ++right;

            if (left + 1 <= height.size() - 1 && height[left] > height[left + 1]) {
                int temp = left + 1;
                while (temp < right) {
                    forward[temp] = height[left] - height[temp];
                    ++temp;
                }
                left = right - 1;
            }
            ++left;
        }

        // 反向遍历
        left = height.size() - 1, right = height.size() - 1;
        while (right >= 0) {
            while (left > 0 && height[left] <= height[right])
                --left;

            if (right - 1 >= 0 && height[right] > height[right - 1]) {
                int temp = right - 1;
                while (temp > left) {
                    backward[temp] = height[right] - height[temp];
                    --temp;
                }
                right = left + 1;
            }
            --right;
        }

        // 计算雨水
        for (int i = 0; i < height.size() - 1; ++i) {
            rain += min(forward[i], backward[i]);
        }
        return rain;
    }
};

2  方法二:动态规划

解题思路:

  1. 正向遍历,算每个区域的局部最大高度(绿色)
  2. 反向遍历,算每个区域的局部最大高度(红色)
  3. 取每个下标的最大高度的较小值再减该下标的高度
  4. 总和为 rain 积水量

事实证明是我没有彻底理解官方题解的思路,所以才搞出了方法一这种智障解法。

力扣官方说明图:

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size();
        vector<int> leftMax(n), rightMax(n);
        if (n == 0) return 0;

        // 正向遍历
        leftMax[0] = height[0];
        for (int i = 1; i < n; ++i) {
            leftMax[i] = max(leftMax[i - 1], height[i]);
        }

        // 反向遍历
        rightMax[n - 1] = height[n - 1];
        for (int i = n - 2; i >= 0; --i) {
            rightMax[i] = max(rightMax[i + 1], height[i]);
        }

        // 计算雨水
        int rain = 0;
        for (int i = 0; i < n; ++i) {
            rain += min(leftMax[i], rightMax[i]) - height[i];
        }

        return rain;
    }
};

3  方法三:双指针

思路说明:

方法二是完成正向遍历和反向遍历后才来计算 rain 积水量,而方法三是利用双指针一左一右同时开始遍历,并且可以直接计算 rain 积水量。

由于每次移动前都立即计算了:

leftMax = max(leftMax, height[left]);
rightMax = max(rightMax, height[right]);

所以下面的两个不等式成立:

  • 若 height[left] < height[right],则必有 leftMax < rightMax
  • 若 height[left] > height[right],则必有 leftMax > rightMax

那么就可以直接计算 rain 积水量了:

  • 若 height[left] < height[right],则 rain += leftMax - height[left]
  • 若 height[left] > height[right],则 rain += rightMax - height[right]

一开始我觉得很难理解,但是动动笔写一下,就知道不等式成立了。比如,对于第一个不等式,就可能存在 height[left] < leftMax < rightMax < height[right] 或者 leftMax < height[left] < rightMax < height[right] 等情形,它们都会使不等式成立。

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size(), rain = 0;
        if (n == 0) return 0;

        int leftMax = 0, rightMax = 0;
        int left = 0, right = n - 1;

        while (left != right) {
            leftMax = max(leftMax, height[left]);
            rightMax = max(rightMax, height[right]);
            if (height[left] < height[right]) {
                rain += leftMax - height[left];
                ++left;
            } else {
                rain += rightMax - height[right];
                --right;
            }
        }

        return rain;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1398495.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CVE2020-1938漏洞复现

这个漏洞是tomcat的 然后我们先了解漏洞产生的原理 首先我们先来看tmocat纠结是干什么的 tomcat是个中间件 最主要的两个结构、 servlet的定义和部分源码&#xff0c; 漏洞就是从这来的 tomcat处理http请求 源码分析 tomcat 8.5.46 哎 这教学视频讲半天看不懂 不看原…

汽车制动器行业调查:市场将继续呈现稳中向好发展态势

汽车制动器是汽车的制动装置&#xff0c;汽车所用的制动器几乎都是摩擦式的&#xff0c;可分为鼓式和盘式两大类。鼓式制动器摩擦副中的旋转元件为制动鼓&#xff0c;其工作表面为圆柱面;盘式制动器的旋转元件则为旋转的制动盘&#xff0c;以端面为工作表面。 目前市场上主流的…

防火墙部署安全区域

目录 为什么需要安全区域在防火墙上如何来区分不同的网络将接口划分到安全区域安全区域、受信任程度与安全级别安全域间、安全策略与报文流动的方向 安全区域配置案例 为什么需要安全区域 防火墙主要部署在网络边界起到隔离的作用 在防火墙上如何来区分不同的网络 防火墙通过安…

基础算法-整数二分

基础算法-整数二分 基本思想——折半 二分法的基本思想比较简单&#xff0c;是用来在数组当中查找特定元素的算法。 二分可以分为整数二分和浮点二分&#xff0c;本文主要介绍整数二分。 具体步骤 首先&#xff0c;从数组的中间元素开始搜索&#xff0c;如果该元素恰好是目标…

【蓝桥杯EDA设计与开发】资料汇总以及立创EDA及PCB相关技术资料汇总(持续更新)

[18/01/2024]&#xff1a;目前为了准备蓝桥杯做一些资料贴&#xff0c;于是写下这一篇博客。 各种资料均来源于网络以及部分书籍、手册等文档&#xff0c;参考不保证其准确性。 如果在准备蓝桥杯&#xff0c;可与我私信共同学习&#xff01;&#xff01;&#xff01;&#xf…

无尽的石头

题目 import java.util.Scanner;public class Main {public static int func(int res) {int sum 0;while(res!0) {int s res%10;sums;res/10;}return sum;}public static void main(String[] args) {Scanner sc new Scanner(System.in);int t sc.nextInt();sc.nextLine();…

浅谈重组IgG抗体表达-泰克生物

一&#xff0e;IgG抗体简介 IgG作为机体的免疫卫士&#xff0c;主要在机体免疫中起保护作用&#xff0c;对抗大部分的细菌和病毒。IgG是唯一能通过胎盘的免疫球蛋白&#xff0c;IgG能够激活补体系统&#xff0c;参与抗体介导的细胞毒性即ADCC作用&#xff0c;同时参与部分超敏反…

如何免费从 SD 卡恢复已删除的文件?(照片、视频、MP3)

今天我们将告诉您如何免费从格式化的 SD 卡或闪存卡恢复文件。 特别是如果您是一名摄影师、博主或任何处理内容的人&#xff0c;您的 SD 卡上有一些内容&#xff0c;但您不小心删除或格式化了&#xff0c;现在您要向自己道歉。 无需担心&#xff0c;因为今天我们将告诉您如何…

Redis在Windows10中安装和配置

1.首先去下载Redis 这里不给出下载地址&#xff0c;自己可以用去搜索一下地址 下载 下载完成后解压到D盘redis下&#xff0c;本人用的是3.2.100 D:\Redis\Redis-x64-3.2.100 2.解压完成后需要设置环境变量&#xff0c;这里新建一个系统环境变量中path 中添加一个文件所…

MobX 的 Observable Array,如何转换成一个普通的数组

问题描述 访问mobx store里面的数据时打印结果为如下&#xff0c;是一个 MobX 的 Observable Array&#xff0c;而不是一个普通的数组。MobX 使用 Proxy 来实现响应式数据&#xff0c;因此打印的结果为的是 Proxy 对象。可是我需要的是实际的数组数据。 Proxy {0: Proxy, 1: …

电脑怎么定时打开指定文件?两种方法教给你

在电脑中定时打开文件&#xff0c;可以帮助我们节省时间&#xff0c;提高操作效率。那么&#xff0c;电脑怎么定时打开指定文件&#xff1f;下面小编就来教你两种方法。 方法一&#xff1a;利用任务计划程序定时打开文件 在“此电脑”上单击鼠标右键&#xff0c;选择“管理”。…

【Vue】vue项目中Uncaught runtime errors:怎样关闭

vue项目中Uncaught runtime errors:怎样关闭 一、背景描述二、报错原因三、解决方案3.1 只显示错误信息不全屏覆盖3.2 取消全屏覆盖 四、参考资料 一、背景描述 项目本来运行的好好&#xff0c;换了个新的浏览器&#xff0c;新的Chrome浏览器版本号是116.0.5845.97&#xff08…

红队渗透靶机:TOPPO: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 5、dirsearch WEB tips1 tips2 SSH登录 提权 系统信息收集 本地 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:69:c7:bf, IPv4: 192.168.110…

采集B站up主视频信息

一、网页信息&#xff08;示例网址&#xff1a;https://space.bilibili.com/3493110839511225/video&#xff09;

基于SSM的KTV包厢管理系统(有报告)。Javaee项目,ssm项目。

演示视频&#xff1a; 基于SSM的KTV包厢管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过…

【极光系列】springBoot集成elasticsearch

【极光系列】springBoot集成elasticsearch 一.gitee地址 直接下载解压可用 https://gitee.com/shawsongyue/aurora.git 模块&#xff1a;aurora_elasticsearch 二.windows安装elasticsearch tips&#xff1a;注意es客户端版本要与java依赖版本一致&#xff0c;目前使用7.6…

掌握大模型这些优化技术,优雅地进行大模型的训练和推理!

ChatGPT于2022年12月初发布&#xff0c;震惊轰动了全世界&#xff0c;发布后的这段时间里&#xff0c;一系列国内外的大模型训练开源项目接踵而至&#xff0c;例如Alpaca、BOOLM、LLaMA、ChatGLM、DeepSpeedChat、ColossalChat等。不论是学术界还是工业界&#xff0c;都有训练大…

5分钟教会你如何在生产环境debug代码

前言 有时出现的线上bug在测试环境死活都不能复现&#xff0c;靠review代码猜测bug出现的原因&#xff0c;然后盲改代码直接在线上测试明显不靠谱。这时我们就需要在生产环境中debug代码&#xff0c;快速找到bug的原因&#xff0c;然后将锅丢出去。 生产环境的代码一般都是关闭…

Peter算法小课堂—拓扑排序与最小生成树

拓扑排序 讲拓扑排序前&#xff0c;我们要先了解什么是DAG树。所谓DAG树&#xff0c;就是指“有向无环图”。请判断下列图是否是DAG图 第一幅图&#xff0c;它不是DAG图&#xff0c;因为它形成了一个环。第二幅图&#xff0c;它也不是DAG图&#xff0c;因为它没有方向。第三幅…

Red Hat Enterprise Linux 6.10 安装图解

引导和开始安装 选择倒计时结束前&#xff0c;通过键盘上下键选择下图框选项&#xff0c;启动图形化安装过程。需要注意的不同主板默认或者自行配置的固件类型不一致&#xff0c;引导界面有所不同。也就是说使用UEFI和BIOS的安装引导界面是不同的&#xff0c;如图所示。若手动调…