leetcode 1326. Minimum Number of Taps to Open to Water a Garden

news2025/2/25 17:05:44

在这里插入图片描述

x轴上的花园范围为[0,n], 0~n这个n+1个离散点上有水龙头,第 i 个水龙头能浇水的范围为[i-ranges[i], i+ranges[i]].
求能浇整个花园的最小水龙头个数。

思路:

方法一
greedy

先把每个水龙头能浇的区间准备好,
用一个数组保存所有区间,数组下标为区间起点,数组内容为区间终点。

然后从左到右遍历这个数组,到这里就和55题Jump Game类似了。
用一个变量canReach表示到目前的水龙头为止能浇到的最远距离。preEnd表示前一个水龙头的区间终点。

如果当前位置 > preEnd,说明需要开一个新的水龙头,
但是如果这时canReach <= preEnd(前一水龙头处能浇到的最远距离也无法到达当前位置,后面有说明),说明无法到达,返回-1.
更新preEnd到canReach (canReach这时还没有更新,即preEnd更新到前一个水龙头为止的最远范围). 水龙头个数+1.
把canReach更新到和当前区间终点相比的较大值。

有一个特殊情况要注意下,就是Example2中ranges[i]=0的情况。
注意能浇水到整个花园说明不止是离散点i , i+1, …能浇到,i 到 i+1之间的连续点部分也必须在区间中。
而ranges[i] = 0 表示只能浇到离散点 i 本身。比如1,2点能浇到,但它们之间的1.1, 1.2, …都不在浇灌范围。
所以在处理区间时,canReach必须能到达当前点才算满足条件。

    public int minTaps(int n, int[] ranges) {
        int preEnd = 0;
        int canReach = 0;
        int[] startEnd = new int[n+1];
        int cnt = 0;

        for(int i = 0; i <= n; i++) {
            if(ranges[i] == 0) continue;
            int start = (i - ranges[i] < 0 ? 0 : i - ranges[i]);
            int end = (i + ranges[i] > n ? n : i + ranges[i]);
            startEnd[start] = end;
        }

        for(int i = 0; i <= n; i++) {
            if(i > preEnd) {
                if(canReach <= preEnd) return -1;
                cnt ++;
                preEnd = canReach;
            }
            if(startEnd[i] > canReach) canReach = startEnd[i];
        }
		//cnt是前一区间满足条件时在当前区间加的,最后一个区间没有下一区间去处理,所以要在最后处理一下
		//如果preEnd能到达最后位置,就不需要cnt+1,如果到不了,需要再cnt++,preEnd更新到canReach
        return cnt + (preEnd < n ? 1 : 0);
    }

方法二

DP
dp[i ] 表示浇到 i 位置所需的水龙头个数。
开始的时候,除了dp[0],其他全部初始化为无穷大。

还是像上面一样从左到右计算每个水龙头的浇水区间。
区间内每个点处所需的最少水龙头个数dp[ i ] = min(dp[i], dp[区间的起点]+1).
这是什么意义呢?
因为dp[0]=0, 当更新水龙头0的区间时,都会以dp[0]+1为准,把0处的水龙头能浇到的范围内,每个点处所需水龙头个数更新为1.
假设第一个区间为[0,2],更新如下
1 1 1 Inf Inf Inf
这时假如进入下一区间[2,4],那么在2的位置,仍然可以保持dp[2]=min(dp[2], dp[2]+1)=1.
到了位置3时,dp[3]=min(Inf,dp[2]+1)就变成需要2个水龙头。
同样的,如果前一范围覆盖不到后面的区间,就会出现min(inf, inf+1)的情况。
最后返回dp[n], 如果dp[n]为Inf, 说明无法浇到整个花园,返回-1.

    public int minTaps(int n, int[] ranges) {
        final int INF = 100000;
        int[] dp = new int[n+1];
        Arrays.fill(dp, INF);
        dp[0] = 0;

        for(int i = 0; i <= n; i++) {
            int start = (i-ranges[i] < 0 ? 0 : i-ranges[i]);
            int end = (i + ranges[i] > n ? n : i+ranges[i]);
            for(int j = start; j <= end; j++){
                dp[j] = Math.min(dp[j], dp[start]+1);
            }
        }
        return dp[n] == INF ? -1 : dp[n];
    }

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

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

相关文章

Node.js 应用的御用品: Node.js 错误处理系统

开发中&#xff0c;有些开发者会积极寻求处理错误&#xff0c;力求减少开发时间&#xff0c;但也有些人完全忽略了错误的存在。正确处理错误不仅意味着能够轻松发现和纠正错误&#xff0c;而且还意味着能够为大型应用程序开发出稳健的代码库。 特别是对于 Node.js 开发人员&am…

uniapp项目实践总结(六)自定义顶部导航栏

本篇主要讲述如何自定义顶部导航栏,有时候默认导航栏不足以满足我们的需求,这时候就需要自定义导航栏来解决这个问题。 目录 默认导航修改配置自定义顶部默认导航 自带的默认顶部导航设置的内容有限,不容易扩展修改,因此如果有更加个性化的需求,则需要自定义顶部导航。 …

中文句子关系推断

本文通过ChnSentiCorp数据集介绍了中文句子关系推断任务过程&#xff0c;主要使用预训练语言模型bert-base-chinese直接在测试集上进行测试&#xff0c;也简要介绍了模型训练流程&#xff0c;不过最后没有保存训练好的模型。 一.任务简介和数据集 通过模型来判断2个句子是否连…

Gazebo仿真环境下的强化学习实现

Gazebo仿真环境下的强化学习实现 主体源码参照《Goal-Driven Autonomous Exploration Through Deep Reinforcement Learning》 文章目录 Gazebo仿真环境下的强化学习实现1. 源码拉取2. 强化学习实现2.1 环境2.2 动作空间2.3 状态空间2.4 奖励空间2.5 TD3训练 3. 总结 1. 源码…

【LeetCode算法系列题解】第41~45题

CONTENTS LeetCode 41. 缺失的第一个正数&#xff08;困难&#xff09;LeetCode 42. 接雨水&#xff08;困难&#xff09;LeetCode 43. 字符串相乘&#xff08;中等&#xff09;LeetCode 44. 通配符匹配&#xff08;困难&#xff09;LeetCode 45. 跳跃游戏 II&#xff08;中等&…

字符和字符串的库函数模拟与实现

前言&#xff1a; 相信大家平常在写代码的时候&#xff0c;用代码解决实际问题时苦于某种功能的实现&#xff0c;而望而止步&#xff0c;这个时候库函数的好处就体现出来了&#xff0c;当然个人代码编写能力强的可以自己创建一个函数&#xff0c;不过相当于库函数来说却是浪费了…

SSM 基于注解的整合实现

一、pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelV…

C++的基类和派生类构造函数

基类的成员函数可以被继承&#xff0c;可以通过派生类的对象访问&#xff0c;但这仅仅指的是普通的成员函数&#xff0c;类的构造函数不能被继承。构造函数不能被继承是有道理的&#xff0c;因为即使继承了&#xff0c;它的名字和派生类的名字也不一样&#xff0c;不能成为派生…

CSC2121A

半桥架构的栅极驱动电路CSC2121A CSC2121系列是一款高性价比的半桥架构的栅极驱动专用电路&#xff0c;用于大功率MOS管、IGBT管栅极驱动。IC内部集成了逻辑信号处理电路、死区时间控制电路、欠压保护电路、电平位移电路、脉冲滤波电路及输出驱动电路&#xff0c;专用于无刷电…

ClickHouse配置Hdfs存储数据

文章目录 背景配置单机配置HA高可用Hdfs集群参考文档 背景 由于公司初始使用Hadoop这一套&#xff0c;所以希望ClickHouse也能使用Hdfs作为存储 看了下ClickHouse的文档&#xff0c;拿Hdfs举例来说&#xff0c;有两种方式来完成&#xff0c;一种是直接关联Hdfs上的数据文件&am…

【python爬虫案例】用python爬豆瓣音乐TOP250排行榜!

文章目录 一、爬虫对象-豆瓣音乐TOP250二、python爬虫代码讲解三、同步视频四、获取完整源码 一、爬虫对象-豆瓣音乐TOP250 您好&#xff0c;我是 马哥python说 &#xff0c;一名10年程序猿。 今天我们分享一期python爬虫案例讲解。爬取对象是&#xff0c;豆瓣音乐TOP250排行…

汇报下卢松松自媒体收入情况

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 9月1日了&#xff0c;2023年还剩最后4个月了&#xff0c;怎么样?梦想是不是越来越远了? 我看很多人都在涌入做自媒体行业&#xff0c;那今天卢松松就给大家汇报下近期卢松松自媒体帐号的收益情况…

2023开学礼《乡村振兴战略下传统村落文化旅游设计》南京农大许少辉八一新书

2023开学礼《乡村振兴战略下传统村落文化旅游设计》南京农大许少辉八一新书

MVC、MVP、MVVM的成本角度结合业务,如何考虑选型?一文了解方方面面

大家都知道&#xff0c;使用架构的目的是使程序模块化&#xff0c;做到模块内部的高聚合和模块之间的低耦合&#xff0c;使得程序在开发的过程中&#xff0c;开发人员只需要专注于一点&#xff0c;提高程序开发的效率。那么MVC、MVP、MVVM&#xff0c;该怎么选&#xff1f;在什…

百万级并发IM即时消息系统(2)

1.用户model type UserBasic struct {gorm.ModelName stringPassWord stringPhone string valid:"matches(^1[3-9]{1}\\d{9}$)"Email string valid:"email"Avatar string //头像Identity stringClientIp s…

Java注解和反射

注解(Java.Annotation) 什么是注解&#xff08;Annotation&#xff09;&#xff1f; Annotation是从JDK5.0开始引入的新技术 Annotation的作用: 不是程序本身&#xff0c;可以对程序作出解释(这一点和注释(comment)没什么区别)可以被其他程序(比如:编译器等)读取Annotation的…

解决uniapp下拉框 内容被覆盖的问题

1. 下拉框 内容被覆盖的问题 场景: 现在是下拉框被表格覆盖了 解决办法: 在表格上添加css 样式来解决这个问题 .add-table{display: static;overflow: visible; } display: static: 将元素会按照默认的布局方式进行显示&#xff0c;不会分为块状或行内元素。 overflow: vi…

【力扣每日一题】2023.9.1 买钢笔和铅笔的方案数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们三个数&#xff0c;一个是我们拥有的钱&#xff0c;一个是钢笔的价格&#xff0c;另一个是铅笔的价格。 问我们一共有几种买笔…

需求管理系统大盘点,谁能问鼎行业王者宝座?

“需求管理系统有哪些&#xff1f;这些品牌引领行业新风潮&#xff1a;Zoho Projects、SAP SuccessFactors、Oracle NetSuite、Microsoft Dynamics 365、Infor CloudSuite、JDA Software。” 需求管理系统是一种专门用于收集、分析和跟踪客户需求的工具&#xff0c;可以帮助企业…

9.1 消息 字体 颜色 文件对话框 发布软件

保存 void Widget::on_savebtn_clicked() {QString filename QFileDialog::getSaveFileName(this, "保存", "C:/Users/yc/Desktop/", "图片 (*.png *.xpm *.jpg);;文本 (*.txt);;所有文件 (*.*)");if(filename.isNull()){QMessageBox::informa…