当前位置: 首页 > 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…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...