【刷题笔记】加油站||符合思维方式

加油站

文章目录

  • 加油站
    • 1 题目描述
    • 2 思路
    • 3 解题方法

1 题目描述

https://leetcode.cn/problems/gas-station/

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

2 思路

正如大部分大佬所言,需要找到最小值所在的点。但是他们的代码写得有些含糊,我希望可以使用一种更加符合直觉的方式。

我们假设从i号加油站出发,然后用一张折线图表示到达每个加油站(最终返回i)时的剩余油量。x轴为加油站号,y轴为剩余油量。一开始的时候,剩余油量为0。首先来看一种可能的情况:

gas  = [4, 3, 1, 2, 7, 4]
cost = [1, 2, 7, 3, 2, 5]

这里我们提供代码来表示从不同的站点出发,到达不同站点时候的剩余油量:

gas  = [4,3,1,2,7,4]
cost = [1,2,7,3,2,5]
# 绘制
fig, axs = plt.subplots(1, 6, figsize=(20, 3))
for s in range(len(gas)):left_gas = [0 for _ in range(len(gas))]for i in range(len(gas)):left_gas[i] = (left_gas[i-1] if i > 0 else 0) + gas[(s + i) % len(gas)] - cost[(s + i) % len(gas)]left_gas.insert(0, 0)x = [(s + i) % len(gas) for i in range(len(gas))]x.append(s)axs[s].plot(range(len(gas) + 1), left_gas)axs[s].scatter(range(len(gas) + 1), left_gas)# 设置 x 轴刻度及标签axs[s].set_xticks(np.arange(len(gas) + 1))axs[s].set_xticklabels(x)# 绘制0刻度线axs[s].axhline(y=0, color='r', linestyle='-')# 将最低点标记出来,最低点的索引为left_gas.index(min(left_gas))axs[s].scatter(left_gas.index(min(left_gas)), min(left_gas), color='r')
plt.show()

在这里插入图片描述

你可以明显地看到从哪里出发,可以安全地开一圈了。(红线为0刻度线,红色点为最小点)

那么我们再举一个不可能开一圈的例子:

gas = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  # 0~9号加油站的油量
cost = [10, 9, 8, 7, 6, 5, 4, 3, 2, 11]  # 0~9号加油站到下一站的消耗

其对应图像为

在这里插入图片描述

我这里也提供对应的绘图代码:

import matplotlib.pyplot as plt
import numpy as npgas = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  # 0~9号加油站的油量
cost = [10, 9, 8, 7, 6, 5, 4, 3, 2, 11]  # 0~9号加油站到下一站的消耗# 绘制
# fig, axs = plt.subplots(1, 10, figsize=(20, 3))
# 上下两行,每行5个子图
fig, axs = plt.subplots(2, 5, figsize=(20, 6))
for s in range(len(gas)):left_gas = [0 for _ in range(len(gas))]for i in range(len(gas)):left_gas[i] = (left_gas[i - 1] if i > 0 else 0) + gas[(s + i) % len(gas)] - cost[(s + i) % len(gas)]left_gas.insert(0, 0)x = [(s + i) % len(gas) for i in range(len(gas))]x.append(s)# 设置 x 轴刻度及标签axs[int(s / 5)][s % 5].set_xticks(np.arange(len(gas) + 1))axs[int(s / 5)][s % 5].set_xticklabels(x)axs[int(s / 5)][s % 5].plot(range(len(gas) + 1), left_gas)axs[int(s / 5)][s % 5].scatter(range(len(gas) + 1), left_gas)# 绘制0刻度线axs[int(s / 5)][s % 5].axhline(y=0, color='r', linestyle='-')# 将最低点标记出来,最低点的索引为left_gas.index(min(left_gas))axs[int(s / 5)][s % 5].scatter(left_gas.index(min(left_gas)), min(left_gas), color='r')# 最低点设置垂直虚线,只往下画axs[int(s / 5)][s % 5].axvline(x=left_gas.index(min(left_gas)), color='r', linestyle='--')
plt.show()

什么情况下能转完一圈?总油量大于等于总耗油量

3 解题方法

其实就是根据直觉,创建一个长度为gas.length + 1(参考上面的图,走一圈回来,相当于一共gas.length+1个站点)的数组left_gas(剩余油量),i位置初始为0,表示为在站点i出发时,剩余油量(或者说,初始油量)为0。

每两个站点之间的增加或者减少量是一定的,即任何两点之间连线的斜率是不变的(gas[i] - cost[i]),只要我们让最低值大于等于0,就可以保证走一圈。怎么让最低值大于等于0?只要我们让最低值为出发点,不就能保证其为0了?也就是能够保证最低点大于等于0。

所以,我们只需要找到最低点即可。

我们设置小车从0号站点出发,然后我们计算每个站点的剩余油量:

class Solution(object):def canCompleteCircuit(self, gas, cost):res = [0 for _ in range(len(gas) + 1)] # 剩余油量,为什么是len(gas) + 1,参考图中的x轴min_index = 0 # 初始站点min_left = 0 # 初始油量for i in range(len(gas)):res[i + 1] = res[i] + gas[i] - cost[i] # 例如,站点1的时候,剩余油量=res[0] + gas[0] - cost[0]if res[i + 1] < min_left: # 记录最低点的值和索引min_left = res[i + 1]min_index = i + 1return -1 if res[-1] < 0 else min_index # 到达最最终点的时候,相当于所有的gas相加,然后减去所有的cost,# 如果返回开头的时候,剩余油量小于0,则返回-1

相比之下,leetcode很多大佬的代码让我有点迷茫(没有说大佬写得不好,只是我有点难理解):

class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {int sum = 0 ;int min_num = Integer.MAX_VALUE;int min_index = 0;for ( int i = 0 ; i < gas.length ; i ++){sum += gas[i] - cost[i];if(sum<=min_num && gas[(i+1)%gas.length] >0){min_index =  i;min_num = sum;}}return sum < 0 ? -1 : (min_index +1 ) % gas.length;}
}

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

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

相关文章

Element-UI Upload 手动上传文件的实现与优化

文章目录 引言第一部分&#xff1a;Element-UI Upload 基本用法1.1 安装 Element-UI1.2 使用 <el-upload> 组件 第二部分&#xff1a;手动上传文件2.1 手动触发上传2.2 手动上传时的文件处理 第三部分&#xff1a;性能优化3.1 并发上传3.2 文件上传限制 结语 &#x1f38…

Jmeter工具学习三——CSV文件、关联、断言

Jmeter学习三——CSV文件和关联 jmeter做功能测试和做性能测试的区别CSV数据文件设置&#xff08;读取外部文件&#xff0c;进行分数据驱动&#xff09;文件设置字段介绍&#xff1a;文件名文件编码如果出现编码问题导致的乱码&#xff0c;如何解决&#xff1f; 变量名忽略首行…

【MATLAB】LMD分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 LMDFFTHHT组合算法是一种基于局部均值分解&#xff08;LMD&#xff09;、快速傅里叶变换&#xff08;FFT&#xff09;和希尔伯特-黄变换&#xff08;HHT&#xff09;的组合算法。 LMD是…

day65

今日回顾内容 web应用 HTTP协议 web应用 一、什么是web应用程序 Web应用程序是一种可以通过Web访问的应用程序&#xff0c;程序的最大好处是用户很容易访问应用程序&#xff0c;用户只需要有浏览器即可&#xff0c;不需要再安装其他软件 对于传统的应用软件来说&#xff0c;…

【iOS-UIImagePickerController访问相机和相册】

【iOS-UIImagePickerController访问相机和相册】 一. UIImagePickerController的介绍1 . UIImagePickerController的作用2 . UIImagePickerController的功能 二 . UIImagePickerController的测试程序 一. UIImagePickerController的介绍 1 . UIImagePickerController的作用 U…

Java小游戏飞翔的小鸟

游戏界面 运行界面 开发准备 1、eclipse开发工具 二、创建游戏窗口 Mains类作为主类&#xff0c;在mian方法下定义一个m1()方法&#xff0c;设置窗口。 //定义一个初始化的游戏窗口方法 public static void m1() {//获取底层窗口界面的工具类JFrame jf new JFrame();//创建…

「Verilog学习笔记」非整数倍数据位宽转换24to128

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 要实现24bit数据至128bit数据的位宽转换&#xff0c;必须要用寄存器将先到达的数据进行缓存。24bit数据至128bit数据&#xff0c;相当于5个输入数据第6个输入数据的拼接成一…

Nacos 2.X核心架构源码剖析

概述 注册中心并发处理&#xff0c;1.4.x 写时复制&#xff0c;2.1.0 读写分离&#xff1b;nacos 一般使用 AP 架构&#xff0c;即临时实例&#xff0c;1.4.x 为 http 请求&#xff0c;2.1.0 优化为 gRPC 协议&#xff1b;源码中使用了大量的事件通知机制和异步定时线程池&…

SpringBootWeb案例_01

Web后端开发_04 SpringBootWeb案例_01 原型展示 成品展示 准备工作 需求&环境搭建 需求说明&#xff1a; 完成tlias智能学习辅助系统的部门管理&#xff0c;员工管理 环境搭建 准备数据库表&#xff08;dept、emp&#xff09;创建springboot工程&#xff0c;引入对应…

初识Spring (Spring 核心与设计思想)

文章目录 什么是 Spring什么是容器什么是 IoC理解 Spring IoCDI 概念 什么是 Spring Spring 官网 官方是这样说的: Spring 让每个人都能更快、更轻松、更安全地进行 Java 编程。春天的 专注于速度、简单性和生产力使其成为全球最受欢迎Java 框架。 我们通常所说的 Spring 指的…

C++类与对象(6)—初始化列表、explicit关键字、static成员

目录 一、初始化列表 1、定义 2、注意事项 3、尽量使用初始化列表初始化 4、初始化顺序 二、 explicit关键字 1、定义 2、特点 三、static成员 1、定义 2、特性 3、例题 一、初始化列表 下面这段代码可以正常编译&#xff1a; class A { private:int _a1;//成员…

CGAN原理讲解与源码

1.CGAN原理 生成器&#xff0c;输入的是c和z&#xff0c;z是随机噪声&#xff0c;c是条件&#xff0c;对应MNIST数据集&#xff0c;要求规定生成数字是几。 输出是生成的虚假图片。 判别器的输入是 1.生成器输出的虚假图片x; 2.对应图片的标签c 来自真实数据集&#xff0c;且…

【深度学习】概率图模型(一)概率图模型理论简介

文章目录 一、概率图模型1. 联合概率表2. 条件独立性假设3. 三个基本问题 二、模型表示1. 有向图模型&#xff08;贝叶斯网络&#xff09;2. 无向图模型&#xff08;马尔可夫网络&#xff09; 三、学习四、推断 概率图模型&#xff08;Probabilistic Graphical Model&#xff0…

ROS知识:卡尔曼滤波

https://en.wikipedia.org/wiki/Kalman_filter 一、提要 在卡尔曼滤波的相关技术文献中,其数学表达看起来都非常晦涩和不透明。这很糟糕,如果您以正确的方式看待卡尔曼滤波器,它实际上非常简单易懂。这里的叙述简单,先决条件也很简单;您所需要的只是对概率和矩阵的基本了解…

【C++】友元

1. 友元的概念 友元的目的就是让一个函数或者类 访问另一个类中私有成员。 友元的三种实现&#xff1a; 全局函数做友元类做友元成员函数做友元 2. 友元的实现方式 2.1 全局函数做友元 #include <iostream> using namespace std; class Building {// 告诉编译器 go…

【Android Gradle】之一小时 Gradle及 wrapper 入门

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。 &#x1f60a; 座右铭&#xff1a;不…

PC删除数据,并提示删除成功

<template<el-button size"mini" type"text">分配权限</el-button><el-button size"mini" type"text" click"btnEditRow(row)">编辑</el-button ><el-popconfirmtitle"这是一段内容确定…

计算机毕业设计springboot+vue高校田径运动会报名管理系统61s38

高校田径运动会管理采用java技术&#xff0c;基于springboot框架&#xff0c;mysql数据库进行开发&#xff0c;实现了首页、个人中心、运动员管理、裁判员管理、场地信息管理、项目类型管理、比赛项目管理、比赛报名管理、比赛成绩管理、通知公告管理、留言板管理、交流论坛、系…

微软发布了Orca 2,一对小型语言模型,它们的性能超越了体积更大的同类产品

尽管全球目睹了OpenAI的权力斗争和大规模辞职&#xff0c;但作为AI领域的长期支持者&#xff0c;微软并没有放慢自己的人工智能努力。今天&#xff0c;由萨提亚纳德拉领导的公司研究部门发布了Orca 2&#xff0c;这是一对小型语言模型&#xff0c;它们在零样本设置下对复杂推理…

数据结构---顺序表

文章目录 线性表线性表的定义线性表分类 顺序表顺次表的存储结构实现顺序表的主要接口函数初始化顺序表顺序表尾插顺序表尾删顺序表头插顺序表头删在指定位置插入数据在指定的位置删除数据头插&#xff0c;头删&#xff0c;尾插&#xff0c;尾删新写法打印顺序表销毁顺序表 线性…