背景

本篇图文是LSGO软件技术团队组织的 第二期基础算法(Leetcode)刻意练习训练营 的打卡任务。本期训练营采用分类别练习的模式,即选择了五个知识点(数组、链表、字符串、树、贪心算法),每个知识点选择了 三个简单、两个中等、一个困难 等级的题目,共计三十道题,利用三十天的时间完成这组刻意练习。

本次任务的知识点:贪心算法

贪心算法(greedy algorithm),又称贪婪算法,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。

贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。

贪心算法与动态规划的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。


题目

  • 题号:134
  • 难度:中等
  • https://leetcode-cn.com/problems/gas-station/

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

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

如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -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 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。

实现

第一种:模拟仿真

首先:只有第i站的gas[i] >= cost[i](加入汽油数 >= 消耗汽油数),才能作为起始加油站。此时剩余油数为Remaining = gas[i] - cost[i]

其次:第i+1站的剩余油数为Remaining += gas[i+1] - cost[i+1]只有Remaining > 0才能前往下一站,否则不能前往下一站。

以此类推,若能跑完一周,则找到起始的加油站。

  • 执行结果:通过
  • 执行用时:236 ms, 在所有 C# 提交中击败了 20.75% 的用户
  • 内存消耗:24.7 MB, 在所有 C# 提交中击败了 14.29% 的用户
public class Solution
{public int CanCompleteCircuit(int[] gas, int[] cost){for (int i = 0; i < gas.Length; i++){if (gas[i] >= cost[i]){if (IsCan(gas,cost,i)){return i;}}}return -1;}private bool IsCan(int[] gas, int[] cost,int index){int Remaining = gas[index] - cost[index];for (int i = 1; i < gas.Length; i++){int j = (index + i) % gas.Length;Remaining += gas[j] - cost[j];if (Remaining < 0){return false;}                }return true;}
}

第二种:连续求和法

易知当总加入汽油数大于等于总消耗油汽油数时,无论如何都有解,关键就在于找出起点。

又因为有解时答案唯一,故可将问题转化为求连续和法,若连续和小于等于0,那么此段中肯定不含可以作起点的油站,将下一个油站记为起点继续计算。

  • 执行结果:通过
  • 执行用时:116 ms, 在所有 C# 提交中击败了 60.38% 的用户
  • 内存消耗:24.7 MB, 在所有 C# 提交中击败了 14.29% 的用户
public class Solution
{public int CanCompleteCircuit(int[] gas, int[] cost){int total = 0;int index = 0;int keeping = 0;for (int i = 0; i < gas.Length; i++){int Remaining = gas[i] - cost[i];total += Remaining;if (keeping > 0){keeping += Remaining;}else{keeping = Remaining;index = i;}}return total < 0 ? -1 : index;}
}

python 语言

  • 执行结果:通过
  • 执行用时:40 ms, 在所有 Python3 提交中击败了 90.29% 的用户
  • 内存消耗:14.3 MB, 在所有 Python3 提交中击败了 5.52% 的用户
class Solution:def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:total, index, keeping = 0, 0, 0for i in range(len(gas)):remaining = gas[i] - cost[i]total += remainingif keeping > 0:keeping += remainingelse:keeping = remainingindex = ireturn -1 if total < 0 else index

往期活动

LSGO软件技术团队会定期开展提升编程技能的刻意练习活动,希望大家能够参与进来一起刻意练习,一起学习进步!

  • Python基础刻意练习活动即将开启,你参加吗?
  • Task01:变量、运算符与数据类型
  • Task02:条件与循环
  • Task03:列表与元组
  • Task04:字符串与序列
  • Task05:函数与Lambda表达式
  • Task06:字典与集合
  • Task07:文件与文件系统
  • Task08:异常处理
  • Task09:else 与 with 语句
  • Task10:类与对象
  • Task11:魔法方法
  • Task12:模块

我是 终身学习者“老马”,一个长期践行“结伴式学习”理念的 中年大叔

我崇尚分享,渴望成长,于2010年创立了“LSGO软件技术团队”,并加入了国内著名的开源组织“Datawhale”,也是“Dre@mtech”、“智能机器人研究中心”和“大数据与哲学社会科学实验室”的一员。

愿我们一起学习,一起进步,相互陪伴,共同成长。

后台回复「搜搜搜」,随机获取电子资源!
欢迎关注,请扫描二维码:

刻意练习:LeetCode实战 -- Task29. 加油站相关推荐

  1. LeetCode实战:排序链表

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Sort a link ...

  2. LeetCode实战:除自身以外数组的乘积

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Given an ar ...

  3. LeetCode实战:二叉树的最近公共祖先

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Given a bin ...

  4. LeetCode实战:二叉搜索树中第K小的元素

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Given a bin ...

  5. LeetCode实战:LRU缓存机制

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Design and ...

  6. LeetCode实战:二叉搜索树的最近公共祖先

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Given a bin ...

  7. LeetCode实战:删除链表中的节点

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Write a fun ...

  8. LeetCode实战:反转链表

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Reverse a s ...

  9. LeetCode实战:相交链表

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Write a pro ...

最新文章

  1. Windbg教程-调试非托管程序的基本命令上
  2. 电源管理 解析_智能电源控制箱
  3. Android笔记 一Android基础知识 摘自第一行代码Android
  4. Jenkins自动部署SpringCloud项目
  5. centos7.9使用rpm安装Jenkins_亲测成功---持续集成部署Jenkins工作笔记0022
  6. SAP License:税-你知道多少?
  7. css3实现进度条的模拟
  8. YUI Compressor Maven
  9. 专利号校验码php,电子专利证书的三种下载操作方法
  10. Ribbon界面开发(C++)
  11. 多图预警——从 RAID 到分布式系统中的副本分布
  12. 开源了一个私人云盘——蓝眼云盘
  13. Redis源码解读(七)——基本类型—dict
  14. 25篇最新CV领域综述性论文速递!涵盖15个方向:目标检测/图像处理/姿态估计/医学影像/人脸识别等方向...
  15. 3.1 埃拉托色尼筛选
  16. Java中为按钮添加监听器(事件处理)四种形式总结
  17. mysql 更新的进度_如何查看mysql执行进度
  18. windows10下载软件下到一半显示需要授权怎么解决
  19. 「UOJ224」「NOI2016」旷野大计算
  20. 电脑默认按住了ctrl键的解决办法

热门文章

  1. Spring Cloud应用开发(三:客户端的负载均衡)
  2. 红旗linux桌面版反应慢,红旗Linux6.0桌面版使用感受
  3. RFID系统的基本工作原理
  4. css代码应该放html哪里,css代码放到哪里?
  5. UI设计培训之如何将设计理论与实践相结合
  6. 机器学习之优雅落地线性回归法
  7. [学习笔记]矩阵乘法及其优化dp
  8. CSS布局之-水平垂直居中
  9. 驱动07.USB驱动程序
  10. Maven工程引入jar包(转)