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

news2024/11/28 0:34:41

加油站

文章目录

  • 加油站
    • 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 np

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号加油站到下一站的消耗

# 绘制
# 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 + 1
        return -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.coloradmin.cn/o/1257012.html

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

相关文章

Blender 连续 5 天遭受大规模 DDoS 攻击

Blender 发布公告指出&#xff0c;在2023年11月18日至23日期间&#xff0c;blender.org 网站遭受了持续的分布式拒绝服务&#xff08;DDoS&#xff09;攻击&#xff0c;攻击者通过不断发送请求导致服务器超载&#xff0c;使网站运营严重中断。此次攻击涉及数百个 IP 地址的僵尸…

高并发系统:它的通用设计方法是什么?

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 我们知道&#xff0c;高并发代表着大流量&#xff0c;高并发系统设计的魅力就在于我们能够凭借自己的聪明才智设计巧妙的方案&#xff0c;从而抵抗巨大流量的冲击&#xff0c;带给用户更好的使用体验。这些方案好似能…

电子学会C/C++编程等级考试2021年09月(三级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:余数相同问题 已知三个正整数 a,b,c。 现有一个大于1的整数x,将其作为除数分别除a,b,c,得到的余数相同。 请问满足上述条件的x的最小值是多少? 数据保证x有解。输入: 一行,三个不大于1000000的正整数a,b,c,两个整数…

ChatGPT初体验:注册、API Key获取与ChatAPI调用详解

自从2022年10月&#xff0c;ChatGPT诞生以后&#xff0c;实际上已经改变了很多&#xff01;其火爆程度简直超乎想象&#xff0c;一周的时间用户过百万&#xff0c;两个月的时间用户过亿。 目前ChatGPT4已经把2023年4月以前的人类的知识都学习到了&#xff0c;在软件工程里面&am…

因子分析例题(多元统计分析期末复习)

例一 设某客观现象可用 X {X} X( X 1 {X_1} X1​&#xff0c; X 2 {X_2} X2​&#xff0c; X 3 {X_3} X3​)’ 来描述&#xff0c;在因子分析时&#xff0c;从约相关阵出发计算特征值为 λ 1 {λ_1} λ1​1.754&#xff0c; λ 2 {λ_2} λ2​1&#xff0c; λ 3 {λ_3} λ3​…

3.数据结构

3.1 数据结构分类 常见的数据结构包括数组、链表、栈、队列、哈希表、树、堆、图&#xff0c;它们可以从“逻辑结构”和“物理结构”两个维度进行分类。 3.1.1逻辑结构&#xff1a;线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中&#xff0c;数据按照…

【docker系列】docker命令篇

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

C语言:有一篇文章,共三行文字,每行有80个字符。要求分别统计出单词个数、空格数。

分析&#xff1a; #include<stdio.h>&#xff1a;这是一个预处理指令&#xff0c;将stdio.h头文件包含到程序中&#xff0c;以便使用输入输出函数。 int main()&#xff1a;这是程序的主函数&#xff0c;是程序执行的入口点。 char a[3][80];&#xff1a;定义了一个二维…

springBoot的实现原理;SpringBoot是什么;使用SpringBoot的核心功能;springBoot核心注解以及核心配置文件

文章目录 springBootspringBoot的实现原理什么是 Spring Boot&#xff1f;SpringBoot是什么为什么要使用springBootSpring Boot的核心功能Spring Boot 主要有如下优点&#xff1a; SpringBoot启动过程-流程Spring Boot 的核心注解是哪个&#xff1f;什么是 JavaConfig&#xff…

7 通用数字量输入输出GPIO

文章目录 7.0 GPIO概念7.1 GPIO工作原理7.2 GPIO寄存器以及编程7.2.5 GPIO寄存器编程设置与应用 7.3 GPIO跑马灯7.3.1 LED 输出初始化7.3.2 跑马灯输出实验7.3.3 按键输入实验 7.0 GPIO概念 GPIO&#xff08;general purpose intput output&#xff09;是通用输入输出端口的简…

Elasticsearch:LangChain 是什么?

当你将应用程序称为 “AI&#xff08;人工智能&#xff09;” 时&#xff0c;这通常意味着它包含与学习模型&#xff08;例如大型语言模型&#xff0c;或 LLM&#xff09;的交互。 [不那么]有趣的事实是&#xff0c;LLM 的使用实际上并不是使应用程序变得智能的原因。 它的特殊…

vue项目npm install报错Failed at the fibersa4.0.3 install script

报错如下 解决&#xff1a;降低node版本 降到12.16.0 参考链接

基于51单片机的全自动洗衣机proteus仿真设计

标题目录 &#x1f4ab;51单片机全自动洗衣机proteus仿真设计&#x1f4ab;设计介绍&#x1f4ab;仿真图电动机驱动模块电路设计电源模块电路设计控制按键进水阀和排水阀控制继电器 &#x1f4ab;程序设计main函数 &#x1f4ab;设计报告&#x1f4ab;资料清单&&下载链…

【古诗生成AI实战】之三——任务加载器与预处理器

本章内容属于数据处理阶段&#xff0c;将分别介绍任务加载器task和预处理器processor。 [1] 数据集 在深入探讨数据处理的具体步骤之前&#xff0c;让我们先了解一下我们将要使用的数据集的形式。 本项目采用的是七绝数据集&#xff0c;总计83072条古诗&#xff0c;其形式如下&…

Linux系统编写C语言程序并执行(图文详解)

目录 前言 Linux如何编写C语言 1.打开编辑器&#xff0c;写代码 2.编译运行文件 相关拓展 前言 LINUX中包含了很多软件开发工具。它们中的很多是用于C和C应用程序开发的。 C是一种能在UNIX的早期就被广泛使用的通用编程语言。它最早是由Bell实验室的Dennis Ritchie为了UN…

中年人怎么发展?持续发展?

现在ai这么火&#xff0c;就像当年的xxx&#xff0c;如果没有抓住&#xff0c;会xxx吗&#xff1f; 为了ai&#xff0c;多学学python也是也是好的啊。 在学习之余&#xff0c;还是想做做自媒体的。不求马上赚到钱。我的想法是&#xff0c;现在每天下班回家都是刷刷抖音&#…

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

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

基于深度学习的图像超分辨率应用

引言 在使用图片浏览软件显示图片时&#xff0c;为了凸显某个部位&#xff0c;你会放大图片&#xff0c;为了显示整体&#xff0c;你会缩小图片。 你的原始图片大小是固定的&#xff0c;但图像浏览软件既可以最大化到整个屏幕&#xff0c;也可以只占一个区域&#xff0c;这些…

【云平台】STM32微信小程序阿里云平台学习板

【云平台】STM32微信小程序阿里云平台学习板 文章目录 前言一、立创EDA&#xff08;硬件设计&#xff09;1.主控STM32F103C8T62.ESP8266模块3.温湿度模块4.光照强度模块5.OLED显示模块6.PCB正面7.PCB反面8.3D视角正面9.3D视角反面 二、【云平台】STM32微信小程序阿里云平台学习…

Linux7设置ssh秘钥登录并关闭密码登录

说明&#xff1a;场景为windows使用WinScp远程登录linux服务 winscp安装教程&#xff1a;winscp安装及关联putty使用_putty.exe没有找到_cherishSpring的博客-CSDN博客 1.在window上生成公钥和秘钥&#xff0c;操作方式参考以下文章第3点&#xff1a; git关联云效使用教程_云…