IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【算法】Gas Station(LeetCode134) -> 正文阅读

[数据结构与算法]【算法】Gas Station(LeetCode134)

1. 概述

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

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

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

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

?

2. 思路与代码

思路
从第一个站开始,记录下达到第 i 个站后还剩下的油,如果 > 0,则说明能够到达第 i 个站,如果 < 0,则说明不能到达第 i 个站,需要从下一个 i + 1 站开始再尝试。

最后需要判断,如果 ∑ i = 0 n ? 1 ( g a s [ i ] ? c o s t [ i ] ) > = 0 \sum_{i=0}^{n-1}(gas[i] - cost[i]) >= 0 i=0n?1?(gas[i]?cost[i])>=0 ,则说明能够从 start 站出发,绕一圈回到 start 站。

代码

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int start = 0, total = 0, cur = 0;
        for (int i = 0; i < gas.length; i++) {
            cur += gas[i] - cost[i];
            total += gas[i] - cost[i];
            if (cur < 0) {
                start = i + 1;
                cur = 0;
            }
        }
        return total < 0? -1 : start;
    }
}

?

3. 证明

cur < 0时意味着无法从第 i 站到达第 i + 1 站,需要从 i + 1 站开始重新尝试,这很好理解,但是为什么 ∑ i = 0 n ? 1 ( g a s [ i ] ? c o s t [ i ] ) > = 0 \sum_{i=0}^{n-1}(gas[i] - cost[i]) >= 0 i=0n?1?(gas[i]?cost[i])>=0 就一定能从 start 站开始绕一圈再回到 start 站呢?

反证法证明
假设存在某一个站 j 使得从 start 到站 j 是可行的,但是从第站到第 j + 1 站是不可行的,其中
j ∈ [ ( s t a r t + n ) % n , ( s t a r t ? 1 + n ) % n ] j∈[(start + n) \% n, (start - 1 + n) \% n] j[(start+n)%n,(start?1+n)%n],那么就有如下两个条件:

  1. ∑ i = 0 n ? 1 ( g a s [ i ] ? c o s t [ i ] ) > = 0 \sum_{i=0}^{n-1}(gas[i] - cost[i]) >= 0 i=0n?1?(gas[i]?cost[i])>=0
  2. ( g a s [ s t a r t ] ? c o s t [ s t a r t ] ) + ( g a s [ s t a r t + 1 ] ? c o s t [ s t a r t + 1 ] ) + . . . + ( g a s [ j ] ? c o s t [ j ] ) < 0 (gas[start] - cost[start]) + (gas[start + 1] - cost[start + 1]) + ... + (gas[j] - cost[j]) < 0 (gas[start]?cost[start])+(gas[start+1]?cost[start+1])+...+(gas[j]?cost[j])<0

那么就可以得出条件3

( g a s [ j + 1 ] ? c o s t [ j + 1 ] ) + ( g a s [ j + 2 ] ? c o s t [ j + 2 ] ) + . . . + ( g a s [ s t a r t ] ? c o s t [ s t a r t ] ) > 0 (gas[j + 1] - cost[j + 1]) + (gas[j + 2] - cost[j + 2]) + ... + (gas[start] - cost[start]) > 0 (gas[j+1]?cost[j+1])+(gas[j+2]?cost[j+2])+...+(gas[start]?cost[start])>0

?
如果

j = start - 1

因为是从 start 站出发的,说明不能从 start - 1 站到达 start 站,而与条件3是相矛盾的,因此 j 不能等于 start - 1。

?
j = start - 2

已知不能从 start - 1 站到达 start 站,因此有

g a s [ s t a r t ] ? c o s t [ s t a r t ] < 0 gas[start] - cost[start] < 0 gas[start]?cost[start]<0

并且有条件3:

( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) + ( g a s [ s t a r t ] ? c o s t [ s t a r t ] ) > 0 (gas[start - 1] - cost[start - 1]) + (gas[start] - cost[start]) > 0 (gas[start?1]?cost[start?1])+(gas[start]?cost[start])>0

那么就有

( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) > 0 (gas[start - 1] - cost[start - 1]) > 0 (gas[start?1]?cost[start?1])>0

也就是说,能够从 start - 2 站开始到达 start - 1 站,而且 ( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) + ( g a s [ s t a r t ] ? c o s t [ s t a r t ] ) > 0 (gas[start - 1] - cost[start - 1]) + (gas[start] - cost[start]) > 0 (gas[start?1]?cost[start?1])+(gas[start]?cost[start])>0,那么从 start - 2 站开始到达了 start - 1 站,可以继续从 start - 1 站到达 start 站,因为剩下的油是够的。

产生了矛盾,因此 j 不能等于 start - 2。

?
j = start - 3

已知不能从 start - 1 站到达 start 站,因此有

g a s [ s t a r t ] ? c o s t [ s t a r t ] < 0 gas[start] - cost[start] < 0 gas[start]?cost[start]<0

并且有条件3:

( g a s [ s t a r t ? 2 ] ? c o s t [ s t a r t ? 2 ] ) + ( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) + ( g a s [ s t a r t ] ? c o s t [ s t a r t ] ) > 0 (gas[start - 2] - cost[start - 2]) + (gas[start - 1] - cost[start - 1]) + (gas[start] - cost[start]) > 0 (gas[start?2]?cost[start?2])+(gas[start?1]?cost[start?1])+(gas[start]?cost[start])>0

如果 g a s [ s t a r t ? 2 ] ? c o s t [ s t a r t ? 2 ] < 0 gas[start - 2] - cost[start - 2] < 0 gas[start?2]?cost[start?2]<0,那么就有 ( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) + ( g a s [ s t a r t ] ? c o s t [ s t a r t ] ) > 0 (gas[start - 1] - cost[start - 1]) + (gas[start] - cost[start]) > 0 (gas[start?1]?cost[start?1])+(gas[start]?cost[start])>0

而根据上面的证明, ( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) + ( g a s [ s t a r t ] ? c o s t [ s t a r t ] ) > 0 (gas[start - 1] - cost[start - 1]) + (gas[start] - cost[start]) > 0 (gas[start?1]?cost[start?1])+(gas[start]?cost[start])>0 是会产生矛盾的,因此必然有 g a s [ s t a r t ? 2 ] ? c o s t [ s t a r t ? 2 ] > = 0 gas[start - 2] - cost[start - 2] >= 0 gas[start?2]?cost[start?2]>=0

也即,从 start - 3 站开始能够到达 start - 2 站。

?
因为 g a s [ s t a r t ] ? c o s t [ s t a r t ] < 0 gas[start] - cost[start] < 0 gas[start]?cost[start]<0,所以必然有

( g a s [ s t a r t ? 2 ] ? c o s t [ s t a r t ? 2 ] ) + ( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) > 0 (gas[start - 2] - cost[start - 2]) + (gas[start - 1] - cost[start - 1]) > 0 (gas[start?2]?cost[start?2])+(gas[start?1]?cost[start?1])>0

那么,根据上面的证明,能从 start - 3 站开始到达 start - 2 站,并且在到达了 start - 2 站后有 ( g a s [ s t a r t ? 2 ] ? c o s t [ s t a r t ? 2 ] ) + ( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) > 0 (gas[start - 2] - cost[start - 2]) + (gas[start - 1] - cost[start - 1]) > 0 (gas[start?2]?cost[start?2])+(gas[start?1]?cost[start?1])>0,也就是油足够从 start - 2 站继续到达 start - 1站。

?
在到达了 start - 1 站后,因为 ( g a s [ s t a r t ? 2 ] ? c o s t [ s t a r t ? 2 ] ) + ( g a s [ s t a r t ? 1 ] ? c o s t [ s t a r t ? 1 ] ) + ( g a s [ s t a r t ] ? c o s t [ s t a r t ] ) > 0 (gas[start - 2] - cost[start - 2]) + (gas[start - 1] - cost[start - 1]) + (gas[start] - cost[start]) > 0 (gas[start?2]?cost[start?2])+(gas[start?1]?cost[start?1])+(gas[start]?cost[start])>0 ,那么剩下的油可以继续从 start - 1 站到达 start 站。

?
因此就出现了矛盾,因此 j 不能等于 start - 3

?
同理可证

同理,可以证明 j 不能取其他的值,也即 j 是不存在的,那么即说明,只要 ∑ i = 0 n ? 1 ( g a s [ i ] ? c o s t [ i ] ) > = 0 \sum_{i=0}^{n-1}(gas[i] - cost[i]) >= 0 i=0n?1?(gas[i]?cost[i])>=0 ,就可以从 start 站绕一圈回到 start 站。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:39:02  更:2022-10-22 21:46:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:46:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码