当前位置: 首页 > news >正文

学习记录:js算法(七十五): 加油站

文章目录

    • 加油站
      • 思路一
      • 思路二
      • 思路三
      • 思路四
      • 思路五

加油站

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gascost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

示例 1:
输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释:
从 3 号加油站(索引为 3)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。示例 2:
输入: gas = [2,3,4], cost = [3,4,3]
输出: -1
解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。

思路一

function canCompleteCircuit(gas, cost) {let totalGas = 0, totalCost = 0, start = 0, tank = 0;for (let i = 0; i < gas.length; i++) {totalGas += gas[i];totalCost += cost[i];tank += gas[i] - cost[i];// 如果当前油量小于0,说明从start点出发无法到达下一个加油站if (tank < 0) {start = i + 1; // 更新起始点tank = 0;      // 清空油箱}}// 如果总的汽油量小于总的消耗量,无法完成环路if (totalGas < totalCost) {return -1;}return start;
}

讲解
可以通过贪心算法解决,主要的思路是寻找一个起始点,从这个点出发,汽车能够通过不断加油并且不耗尽油箱中的油,完成整个环路的行驶。下面详细介绍解题思路和代码实现。

  1. 初始化变量:totalGastotalCost 分别用来累计所有加油站的汽油总量和消耗的汽油总量。start 用来记录可能的起始加油站的索引,tank 则记录当前油箱里的油量。
  2. 遍历加油站:从第一个加油站开始遍历,对于每个加油站,做以下操作:
    ○ 更新油箱里的油量:tank += gas[i] - cost[i]
    ○ 如果油箱里的油量小于**0,说明从当前的 start 点出发无法到达下一个加油站,因此重置 start 点为下一个加油站的位置,并清空油箱:**start = i + 1tank = 0
    ○ 累计总汽油量和总消耗量:totalGas += gas[i] 和 totalCost += cost[i]
  3. 判断能否完成环路:如果 totalGas < totalCost,说明总的汽油量不足以完成整个环路的行驶,返回 -1。否则,从 start 点出发一定可以完成环路,返回 start

思路二

var canCompleteCircuit = function (gas, cost) {const n = gas.length;for (let start = 0; start < n; start++) {let totalGas = 0;let totalCost = 0;let canComplete = true;for (let i = 0; i < n; i++) {const index = (start + i) % n;totalGas += gas[index];totalCost += cost[index];if (totalGas < totalCost) {canComplete = false;break;}}if (canComplete) {return start;}}return -1;
};

讲解
这段代码定义了一个函数 canCompleteCircuit,用于判断在一个环形路线上,是否可以从某个加油站出发,顺利完成一圈而不耗尽汽油。

  1. 输入参数:函数接收两个数组 gascost,分别表示每个加油站的汽油量和从一个加油站到下一个加油站所需的汽油量。
  2. 获取加油站数量:通过 gas.length 获取加油站的数量,并存储在变量 n 中。
  3. 外层循环:遍历每一个加油站,尝试将其作为出发点。循环变量 start 从 0 到 n-1
  4. 初始化变量:
    • totalGas 用于记录从当前出发点出发的总汽油量。
    • totalCost 用于记录从当前出发点到下一个加油站的总消耗量。
    • canComplete 标记从当前起点出发是否可以完成一圈,初始设为 true
  5. 内层循环:从当前起点出发,遍历所有加油站。循环变量 i 从 0 到 n-1
    • 计算当前加油站的索引,使用取模运算以实现环形效果。
  6. 累加汽油量和消耗量:将当前加油站的汽油量加到 totalGas,将消耗量加到 totalCost
  7. 检查能否继续行驶:如果 totalGas 小于 totalCost,说明无法继续行驶,设置 canCompletefalse,并跳出内层循环。
  8. 判断能否完成一圈:如果 canComplete 仍为 true,说明可以从当前起点出发完成一圈,返回当前起点的索引。
  9. 返回结果:如果所有加油站都尝试过后仍然没有找到可以完成一圈的起点,返回 -1,表示无法完成。

思路三

var canCompleteCircuit = function (gas, cost) {const n = gas.length;const prefix = new Array(n + 1).fill(0);for (let i = 0; i < n; i++) {prefix[i + 1] = prefix[i] + gas[i] - cost[i];}let minPrefix = Infinity;let startIndex = 0;for (let i = 1; i <= n; i++) {if (prefix[i] < minPrefix) {minPrefix = prefix[i];startIndex = i;}}return prefix[n] >= 0 ? (startIndex % n) : -1;
};

讲解
这段代码实现了一个函数 canCompleteCircuit,用于判断在一个环形路线上,是否可以从某个加油站出发,顺利完成一圈而不耗尽汽油。

  1. 输入参数:函数接收两个数组 gascost,分别表示每个加油站的汽油量和从一个加油站到下一个加油站所需的汽油量。
  2. 获取加油站数量:通过 gas.length 获取加油站的数量,并存储在变量 n 中。
  3. 初始化前缀数组:创建一个长度为 n + 1 的数组 prefix,并用 0 填充。这个数组用于存储从起点到每个加油站的净汽油量(汽油量减去消耗量)。
  4. 计算前缀和:
    • 使用循环遍历每个加油站,更新 prefix 数组。prefix[i + 1] 存储到达第 i 个加油站后的净汽油量。
    • 计算公式为 prefix[i + 1] = prefix[i] + gas[i] - cost[i]
  5. 寻找最小前缀和:
    • 初始化 minPrefix 为正无穷,startIndex0
    • 再次遍历 prefix 数组,寻找最小的前缀和,并记录其索引 startIndex
  6. 判断是否可以完成一圈:
    • 如果 prefix[n](即完成一圈后的净汽油量)大于等于 0,说明可以完成一圈,返回 startIndex % n 作为起点。
    • 如果 prefix[n] 小于 0,返回 -1,表示无法完成。

思路四

var canCompleteCircuit = function (gas, cost) {const n = gas.length;let totalGas = 0;let totalCost = 0;let currentGas = 0;let startIndex = 0;for (let i = 0; i < n; i++) {totalGas += gas[i];totalCost += cost[i];currentGas += gas[i] - cost[i];if (currentGas < 0) {startIndex = i + 1;currentGas = 0;}}return totalGas >= totalCost ? startIndex : -1;
};

讲解
这段代码实现了一个函数 canCompleteCircuit,用于判断在一个环形路线上,是否可以从某个加油站出发,顺利完成一圈而不耗尽汽油。

  1. 输入参数
    • gas: 一个数组,表示每个加油站的汽油量。
    • cost: 一个数组,表示从一个加油站到下一个加油站所需的汽油量。
  2. 变量初始化
    • n: 加油站的数量。
    • totalGas: 用于累加所有加油站的汽油量。
    • totalCost: 用于累加所有加油站的消耗量。
    • currentGas: 用于跟踪当前剩余的汽油量。
    • startIndex: 记录可行的起始加油站索引。
  3. 遍历加油站
    • 使用 for 循环遍历每个加油站。
    • 在每次迭代中,更新 totalGastotalCost,并计算 currentGas(当前剩余汽油量)。
  4. 判断当前汽油量
    • 如果 currentGas 小于 0,说明从当前 startIndex 到第 i 个加油站无法完成,更新 startIndexi + 1,并重置 currentGas
  5. 返回结果
    • 在循环结束后,检查 totalGas 是否大于或等于 totalCost。如果是,返回 startIndex,否则返回 -1,表示无法完成一圈。

思路五

var canCompleteCircuit = function (gas, cost) {
const n = gas.length;const dp = new Array(n).fill(0);for (let i = 0; i < n; i++) {dp[i] = gas[i] - cost[i];}let totalGas = 0;let totalCost = 0;let currentGas = 0;let startIndex = 0;for (let i = 0; i < n; i++) {totalGas += gas[i];totalCost += cost[i];currentGas += dp[i];if (currentGas < 0) {startIndex = i + 1;currentGas = 0;}}return totalGas >= totalCost ? startIndex : -1;
};

讲解
这段代码通过使用一个额外的数组 dp 来存储每个加油站的净汽油量,并通过一次遍历(时间复杂度 O(n))有效地判断是否存在一个起点,使得从该起点出发能够完成一圈。这种方法同样比暴力法更高效,适用于大规模数据处理。

  1. 输入参数

    • gas: 一个数组,表示每个加油站的汽油量。
    • cost: 一个数组,表示从一个加油站到下一个加油站所需的汽油量。
  2. 变量初始化

    • n: 加油站的数量。
    • dp: 一个数组,用于存储每个加油站的净汽油量(gas[i] - cost[i])。
    • totalGas: 用于累加所有加油站的汽油量。
    • totalCost: 用于累加所有加油站的消耗量。
    • currentGas: 用于跟踪当前剩余的汽油量。
    • startIndex: 记录可行的起始加油站索引。
  3. 计算净汽油量

    • 使用 for 循环遍历每个加油站,将 dp[i] 设置为 gas[i] - cost[i],表示从第 i 个加油站出发的净汽油量。
  4. 遍历加油站

    • 再次使用 for 循环遍历每个加油站。
    • 在每次迭代中,更新 totalGastotalCost,并计算 currentGas(当前剩余汽油量)。
  5. 判断当前汽油量

    • 如果 currentGas 小于 0,说明从当前 startIndex 到第 i 个加油站无法完成,更新 startIndexi + 1,并重置 currentGas
  6. 返回结果

    • 在循环结束后,检查 totalGas 是否大于或等于 totalCost。如果是,返回 startIndex,否则返回 -1,表示无法完成一圈。

相关文章:

学习记录:js算法(七十五): 加油站

文章目录 加油站思路一思路二思路三思路四思路五 加油站 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xf…...

强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断

强心剂&#xff01;EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断 目录 强心剂&#xff01;EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断效果一览基本介绍程序设计参考资料 效果一览 基本介绍 EEMD-MPE-KPCA-LSTM(集合经验模态分解-多尺…...

yarn的安装与使用以及与npm的区别(安装过程中可能会遇到的问题)

一、yarn的安装 使用npm就可以进行安装 但是需要注意的一点是yarn的使用和node版本是有关系的必须是16.0以上的版本。 输入以下代码就可以实现yarn的安装 npm install -g yarn 再通过版本号的检查来确定&#xff0c;yarn是否安装成功 yarn -v二、遇到的问题 1、问题描述…...

大数据行业预测

大数据行业预测 编译 李升伟 和所有预测一样&#xff0c;我们必须谨慎对待这些预测&#xff0c;因为其中一些预测可能成不了事实。当然&#xff0c;真正改变游戏规则的创新往往出乎意料&#xff0c;甚至让最警惕的预言家也措手不及。所以&#xff0c;如果在来年发生了一些惊天…...

可能是NextJs(使用ssr、api route)打包成桌面端(nextron、electron、tauri)的最佳解决方式

可能是NextJs(使用ssr、api route)打包成桌面端(nextron、electron、tauri)的最佳解决方式 前言 在我使用nextron&#xff08;nextelectron&#xff09;写了一个项目后打包发现nextron等一系列桌面端框架在生产环境是不支持next的ssr也就是api route功能的这就导致我非常难受&…...

二百七十、Kettle——ClickHouse中增量导入清洗数据错误表

一、目的 比如原始数据100条&#xff0c;清洗后&#xff0c;90条正确数据在DWD层清洗表&#xff0c;10条错误数据在DWD层清洗数据错误表&#xff0c;所以清洗数据错误表任务一定要放在清洗表任务之后。 更关键的是&#xff0c;Hive中原本的SQL语句&#xff0c;放在ClickHouse…...

CentOS6升级OpenSSH9.2和OpenSSL3

文章目录 1.说明2.下载地址3.升级OpenSSL4.安装telnet 服务4.1.安装 telnet 服务4.2 关闭防火墙4.2.使用 telnet 连接 5.升级OpenSSH5.1.安装相关命令依赖5.2.备份原 ssh 配置5.3.卸载原有的 OpenSSH5.4.安装 OpenSSH5.5.修改 ssh 配置文件5.6关闭 selinux5.7.重启 OpenSSH 1.说…...

2024 年 MathorCup 数学应用挑战赛——大数据竞赛-赛道 A:台风的分类与预测

2024年MathorCup大数据挑战赛-赛道A初赛--思路https://download.csdn.net/download/qq_52590045/89922904↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓…...

kotlin实现viewpager

说明:kotlin tablayout viewpager adapter实现滑动界面 效果图 step1: package com.example.flushfragmentdemoimport androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.…...

RabbitMQ最新版本4.0.2在Windows下的安装及使用

RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;提供可靠的消息传递和队列服务。它支持多种消息协议&#xff0c;包括 AMQP、STOMP、MQTT 等。本文将详细介绍如何在 Windows 系统上安装和使用最新版本的 RabbitMQ 4.0.2。 前言 RabbitMQ 是用 Erlang 语言开发的 AMQP&…...

东方博宜1180 - 数字出现次数

问题描述 有 50 个数&#xff08; 0∼19&#xff09;&#xff0c;求这 50个数中相同数字出现的最多次数为几次&#xff1f; 输入 50 个数字。 输出 1 个数字&#xff08;即相同数字出现的最多次数&#xff09;。 样例 输入 1 10 2 0 15 8 12 7 0 3 15 0 15 18 16 7 17 16 9 …...

LeetCode: 3274. 检查棋盘方格颜色是否相同

一、题目 给你两个字符串 coordinate1 和 coordinate2&#xff0c;代表 8 x 8 国际象棋棋盘上的两个方格的坐标。   以下是棋盘的参考图。   如果这两个方格颜色相同&#xff0c;返回 true&#xff0c;否则返回 false。   坐标总是表示有效的棋盘方格。坐标的格式总是先…...

datax编译并测试

mvn -U clean package assembly:assembly -Dmaven.test.skiptrue 参看&#xff1a;DataX导数的坑_datax插件初始化错误, 该问题通常是由于datax安装错误引起,请联系您的运维解决-CSDN博客 两边表结构先创建好&#xff1a; (base) [rootlnpg bin]# pwd /db/DataX-datax_v20230…...

2-133 基于matlab的粒子群算法PSO优化BP神经网络

基于matlab的粒子群算法PSO优化BP神经网络&#xff0c;BP神经网络算法采用梯度下降算法&#xff0c;以输出误差平方最小为目标&#xff0c;采用误差反向传播&#xff0c;训练网络节点权值和偏置值&#xff0c;得到训练模型。BP神经网络的结构(层数、每层节点个数)较复杂时&…...

复盘秋招22场面试(四)形势重新评估与后续措施

连续好多天睡不着觉&#xff0c;经常晚上起来好几次&#xff0c;到现在还是没offer。之前有个校友在抖音留言说我能收到这么多面试说明简历没问题&#xff0c;这么多一面挂&#xff0c;说明我技术面有问题。确实有一些是kpi面&#xff0c;但是我复盘之后我发现也没有那么多kpi面…...

揭开C++ STL的神秘面纱之string:提升编程效率的秘密武器

目录 &#x1f680;0.前言 &#x1f688;1.string 构造函数 &#x1f69d;1.1string构造函数 &#x1f69d;1.2string拷贝构造函数 &#x1f688;2.string类的使用 &#x1f69d;2.1.查询元素个数或空间 返回字符串中有效字符的个数&#xff1a;size lenth 返回字符串目…...

用人工智能,应该怎么掏钱?

人工智能&#xff08;AI&#xff09;服务的发展正快速改变企业和开发者的工作方式&#xff0c;不仅提供了强大的数据分析和预测能力&#xff0c;还涵盖了从自然语言处理到图像识别的广泛功能。然而&#xff0c;理解AI服务的支付模式对成本控制和合理资源分配至关重要&#xff0…...

【Axure高保真原型】移动案例

今天和大家分享多个常用的移动案例的原型模板&#xff0c;包括轮盘滑动控制元件移动、页面按钮控制元件移动、鼠标单击控制元件移动、元件跟随鼠标移动、鼠标拖动控制元件移动、键盘方向键控制元件移动&#xff0c;具体效果可以点击下方视频观看或打开下方预览地址查看哦 【原…...

Bytebase 3.0.0 - AI 助手全面升级

&#x1f680; 新功能 SQL 编辑器里的 AI 助手&#xff1a;支持将自然语言转换成 SQL 语句&#xff0c;解释 SQL 代码&#xff0c;还能帮助发现潜在问题。 支持 SQL Server DML 语句一键回滚。支持 MariaDB 的在线大表变更。新的 SQL 审核规则&#xff1a; 要求为 MySQL 设置 …...

php基础:数据类型、常量、字符串

语法补充&#xff1a; 每句必须以&#xff1b;结尾 echo&#xff1a;能输出一个以上的字符串&#xff0c;英文逗号隔开 print&#xff1a;只能输出一个字符串并返回1 1.数据类型 php可以自动识别数据类型。 php有5种数据类型&#xff1a;String&#xff08;字符串&#xf…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...