笔记88:LeetCode_134_加油站

前言:


前言1:这个题的题目条件给的不太严谨,题目描述中说“如果存在解,则保证它是唯一的”,通过我的实践,我发现这句话的意思其实是本题的所有样例只有两种情况,无解/有唯一解;而不可能存在多个解的情况;

注:可以使用样例【gas=(10,10,10,10,10)    cost=(1,1,1,1,1)】来验证,这个样例每个节点都可以作为起点,即样例存在多个解,但是运行后LeetCode会报错;

a

a

前言2:这个题在代码随想录上的答案也没有写清楚他的思路,而且答案提供的暴力解法超过了时间复杂度,我提供一下我的暴力解法,并将用自己的语言讲清楚我做这道题时的思路;


a

a

a

a

a

方法1:暴力求解

注:这个题看似使用暴力很简单,但是暴力其实也有一些小坑,如果不想清楚,很难直接过;


思路1:很明显暴力一定是两个循环嵌套起来的,外层使用for循环选择起点,内层则使用while循环从该起点开始一直向后开车,验证能否从新回到起点;

思路2:外层循环很好写,但是我们需要考虑一下内层循环怎么写,选择什么条件来跳出while循环呢?我定义了变量sum_gas来代表从起点走到某一个节点时邮箱里的剩余油量,那么选择【sum_gas < 0】作为跳出条件是绝对没问题的,即如果走到当前节点时邮箱里的油为负,说明选择的起点到不了这个节点,也就无法完成闭环操作;

样例1图解

初始版本代码:这个版本的代码逻辑上完全没有问题,样例都过了,但是提交运行超时了;

class Solution {
public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {//自己尝试:暴力求解for(int i = 0; i < gas.size(); i++) {if(gas[i] == 0) continue;                       //剪枝:如果起点加油站没有,那车辆根本无法行使int ptr = i;                                    //选择起点为ptrint sum_gas = gas[ptr] - cost[ptr];             //以ptr为当前出发站点,如果往后行驶一站,车的剩余油量while(sum_gas >= 0) {ptr = (ptr + 1) % gas.size();               //切换当前出发站点为ptrif(ptr == i) return i;sum_gas = sum_gas + gas[ptr] - cost[ptr];   //以ptr为当前出发站点,如果往后行驶一站,车的剩余油量}}return -1;}
};

思路3:但是我现在还是不太甘心放弃使用暴力搜索,那么我想是否可以通过剪枝操作来优化一点点代码的时间复杂度?使得可以通过提交?如果要剪枝,那就只有两种情况可以剪枝,因为通过这个题的描述我们可知,这个题只有两种情况,要么无解,要么有唯一解;所以我们如何可以在还没有满足【sum_gas < 0】这个条件的时候,就可以提前知道选择当前的这个起点,到底是无解,还是有唯一解?

思路4:我们考虑一种特殊情况,即【sum_gas == 0】这种情况;如果起点到当前节点的sum_gas == 0,那么只可能有两种情况,要么无解,要么有多个解;

看下图进行分析:如果从起点x到节点z的sum_gas == 0,那么我们针对节点y进行思考;如果从节点z开始前进,那么有两种可能:

  • 节点z无法到达节点x:则代表以节点x为起点,是不可能重新回到起点的,即无解;
  • 节点z可以到达节点x:则节点x和节点z作为起点,都可以重新回到本身的位置,即解不唯一;

思路5:所以我们不用看到【sum_gas < 0】才跳出while循环,而可以看到【sum_gas <= 0】就跳出循环;这样就节省了时间复杂度;但是有一个特殊情况,如果从起点回到起点的过程中sum_gas == 0,那么这个时候在起点的前一个点会得到sum_gas == 0;

改进版本代码:改动一共两处

class Solution {
public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {//自己尝试:暴力求解for(int i = 0; i < gas.size(); i++) {if(gas[i] == 0) continue;                       //剪枝:如果起点加油站没有,那车辆根本无法行使int ptr = i;                                    //选择起点为ptrint sum_gas = gas[ptr] - cost[ptr];             //以ptr为当前出发站点,如果往后行驶一站,车的剩余油量while(sum_gas > 0) {ptr = (ptr + 1) % gas.size();               //切换当前出发站点为ptrif(ptr == i) return i;sum_gas = sum_gas + gas[ptr] - cost[ptr];   //以ptr为当前出发站点,如果往后行驶一站,车的剩余油量}//剪枝:特殊情况 -- 从起点回到起点后车辆剩余油量为0if(sum_gas == 0 && ptr == (i + gas.size() - 1) % gas.size()) return i;}return -1;}
};

a

a

a

a

a

方法2:贪心算法

注:使用暴力算法时间复杂度为O(n^{2}),还是太高很容易过不了提交,有没有其他的算法可以将时间复杂度降到O(n)或者O(logn)之类的;


样例1图解:

思路1:我们知道对于节点x,如果他的【gas[x] - cost[x] <= 0】,那么他一定不能作为起点;小于零的情况不用多说,等于零的情况在上面讨论过,要么是无解要么是多个解;所以只要节点x的【gas[x] - cost[x] <= 0】,就意味着这个节点不可以作为起点;只有【gas[x] - cost[x] > 0】的节点才有作为起点的潜质;

思路2:那么对于一串节点的temp_sum值,如果temp_sum小于等于0,是否也意味着这一串节点都是不能作为起点的呢?答案是肯定的;如下如示例,从节点x到节点n的temp_sum为0,那么意味着所有的节点都不可作为起点;

  • 本身作为起点的节点x和其中【gas[] - cost[] <= 0】的节点y和节点m,自不必说肯定不能作为起点;
  • 而节点z满足【gas[z] - cost[z] > 0】却也不能作为起点,是因为本身从节点x到节点z的【temp_sum > 0】,再加之节点z本身z满足【gas[z] - cost[z] > 0】,就这样两个正数相加,都不能突破节点m的封锁,导致在节点n处仍有【temp_sum = 0】,那么如果直接将节点z作为起点,那情况肯定更糟糕,更到达不了节点n了;

思路3:因此我们可以只用一个for循环,遍历所有的点,且每个点只访问一次,如果在这个点处获得的【temp_sum <= 0】,那么就意味着到当前位置的所有节点都不能作为起点;只能再遍历后面的节点,寻找具有成为起点潜质的新节点;

思路4:那如何判断一个节点可以作为起点,且可以回到本身?那么就需要遍历数组到头的时候,有【sum >= 0】,即可知道当前起点是满足答案约束的;在我的代码中,特殊情况(从第一个节点到最后一个节点的sum = 0)已经被包含进去了;

贪心算法代码:

class Solution {
public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {//自己尝试:贪心算法int start = 0;      //起点位置(即temp_sum的开头元素)int sum = 0;        //到当前节点时的剩余油量int temp_sum = 0;   //从起点到当前位置时的剩余油量for(int i = 0; i < gas.size(); i++) {sum = sum + gas[i] - cost[i];temp_sum = temp_sum + gas[i] - cost[i];if(temp_sum <= 0) {temp_sum = 0;start = i + 1;}}if(sum >= 0) return (start % gas.size());return -1;}
};

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

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

相关文章

迅睿 CMS 中开启【ionCube 扩展】的方法

有时候我们想要某种功能时会到迅睿 CMS 插件市场中找现有的插件&#xff0c;但会有些担心插件是否适合自己的需求。于是迅睿 CMS 考虑到这一层推出了【申请试用】&#xff0c;可以让用户申请试用 30 天&#xff0c;不过试用是有条件的&#xff0c;条件如下&#xff1a; php 版…

Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人

Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人&#xff0c;旨在提供多领域的智能对话服务。Midjourney在不同领域中有不同的定义和应用&#xff0c;以下是对其中两个主要领域的介绍&#xff1a; Midjourney官网&#xff1a;https://www.midjourney.com/ 一、AI绘画工…

Windows11搭建Flutter3开发环境

下载&#xff1a;https://docs.flutter.cn/get-started/install/windows/desktop?tabdownload 下载以后解压到C盘&#xff1a; 将bin目录添加到环境变量PATH&#xff1a; 打开终端&#xff0c;输入&#xff1a; flutter doctor执行下面的命令&#xff0c;同意安卓协议&am…

llama3-8b-instruct-262k微调过程的问题笔记(场景为llama论文审稿)

目录 一、环境配置 1.1、模型 1.2、微调环境 1.3、微调数据 二、发现的问题 2.1、过拟合问题 2.2、Qlora zero3 保存模型时OOM问题(已解决) 一、环境配置 1.1、模型 llama3-8b-instruct-262k &#xff08;英文&#xff09; 1.2、微调环境 Package Version ------------------…

开关电源AC-DC(15W 3-18V可调)

简介: 该模块使用PI的TNY268PN电源芯片制作的开关电源,实现最大功率15W 3-18V可调输出(更改反馈电阻)隔离式反激电源; 简介:该模块使用PI的TNY268PN电源芯片制作的开关电源,实现最大功率15W 3-18V可调输出(更改反馈电阻,现电路图输出5V)隔离式反激电源; 一、产品简…

【C++】详解AVL树——平衡二叉搜索树

个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 祝福语&#xff1a;愿你拥抱自由的风 目录 二叉搜索树 AVL树概述 平衡因子 旋转情况分类 左单旋 右单旋 左右双旋 右左双旋 AVL树节点设计 AVL树设计 详解单旋 左单旋 右单旋 详解双旋 左右双旋 平衡因子情况如…

ESP32 接入点灯科技实现远程控制(物联网)

文章目录 ESP32-C3MQTT协议blinker App 源码blinker 开发者Arduino 支持文档导入 blinker 库注册点灯 APPblinker WiFi 示例blinker 蓝牙示例 本示例中开发板使用的是Seeed Studio (XIAO-ESP32-C3) ESP32-C3 ESP32-C3 是 Espressif Systems 公司开发的一款单核 Wi-Fi 和蓝牙双模…

「云渲染课堂」3dmax地砖材质参数怎么让画面更加真实?

在3DMAX中&#xff0c;地砖材质的渲染需要细致的调整&#xff0c;因为不同材质的地砖在反射和折射参数上各不相同。为了使地砖材质更加逼真&#xff0c;以下简要说明了一些设置方法&#xff0c;希望对大家有所帮助&#xff01; 3dmax地砖材质参数如何设置 1、打开材质编辑器&a…

性能测试--线程的监控

1.线程的状态 1.1.线程的5种状态 java的线程总共有5种状态&#xff0c;如下&#xff1a; * 新建&#xff1a;new 【新建之后不启用都是new】* 运行&#xff1a;runnable* 等待&#xff1a;waitting(无限期等待),timed waitting(限期等待)* 阻塞&#xff1a;blocked* 结束&am…

LaTex 模板 - 东北师范大学申研申博推荐信

文章目录 NENU-Letter-Template项目地址示例特性项目结构如何使用main.texletterContent.tex 如何编译方式 1 &#xff1a;在线编译方式 2 &#xff1a;本地编译 参考 NENU-Letter-Template NENU’s recommendation letter template. 东北师范大学推荐信模板 项目地址 GitHu…

网络爬虫原理及其应用

你是否想知道Google 和 Bing 等搜索引擎如何收集搜索结果中显示的所有数据。这是因为搜索引擎对其档案中的所有页面建立索引&#xff0c;以便它们可以根据查询返回最相关的结果。网络爬虫使搜索引擎能够处理这个过程。 本文重点介绍了网络爬虫的重要方面、网络爬虫为何重要、其…

【学习笔记】Webpack5(Ⅱ)

Webpack 3、高级篇 3.1、提升开发体验 —— SourceMap 3.2、提升打包速度 3.2.1 HotModuleReplacement 3.2.2 OneOf 3.2.3 Include / Exclude 3.2.4 Cache 3.2.5 Thread 3.3、减少代码体积 …

蓝桥杯杨辉三角

PREV-282 杨辉三角形【第十二届】【蓝桥杯省赛】【B组】 &#xff08;二分查找 递推&#xff09;&#xff1a; 解析&#xff1a; 1.杨辉三角具有对称性&#xff1a; 2.杨辉三角具有一定规律 通过观察发现&#xff0c;第一次出现的地方一定在左部靠右的位置&#xff0c;所以从…

FTP协议——BFTPD安装(Linux)

1、简介 BFTPD&#xff0c;全称为 Brutal File Transfer Protocol Daemon&#xff0c;是一个用于Unix和类Unix系统的轻量级FTP服务器软件。它的设计理念是提供一个简单、快速、安全的FTP服务器解决方案&#xff0c;特别适用于需要低资源占用的环境。 2、步骤 环境&#xff1…

正在直播:Microsoft Copilot Studio 新增支持Copilot代理、Copilot扩展等多项功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

java连接ldap实现查询

文章目录 一、项目背景二、准备工作三、验证结果四、易错点讲解易错点1&#xff1a;java: 无法访问org.springframework.ldap.core.LdapTemplate易错点2&#xff1a;java: 无法访问org.springframework.context.ConfigurableApplicationContext易错点3&#xff1a;[LDAP: error…

STM32 学习——1. STM32最小系统

这是一个最小系统的测试&#xff0c;LED灯会进行闪烁。选用PC13口&#xff0c;因为STM32F103C8T6 硬件开发板中&#xff0c;这个端口是一个LED 1. proteus8.15 原理图 2. cubemx 新建工程 3. keil 代码 while (1){HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);HAL_Delay(100);…

WGCAT工单系统如何配置通知

WGCAT工单系统可以配置邮件通知 只要配置了邮件通知&#xff0c;那么一旦我们账号有新的工单需要处理&#xff0c;就会接受到邮件通知 除了邮件之外&#xff0c;还可以配置其他方式的通知&#xff0c;比如微信钉钉短信等方式&#xff0c;参考如下 https://www.wgstart.com/wgc…

机器学习(五) -- 监督学习(5) -- 线性回归1

系列文章目录及链接 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;4&#xff09; -- 集成学习方法 - 随机森林 下篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;5&#xff09; -- 线性回归2 前言 tips&#xff1…

Jmeter例题分析-作业一

作业 作业1概要 本文档是关于执行软件性能测试的详细指南&#xff0c;包括使用JMeter工具进行测试的步骤和要求。 文档分为两个主要部分&#xff1a;性能测试的执行和性能测试报告的编写。 在第一部分中&#xff0c;详细描述了如何使用 JMeter进行性能测试。这包括设置测试环…