Gas Station

There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.

Greedy

SOLUTION 1:

引自Lexi's Leetcode solutions 的解答:

  1. 从i开始,j是当前station的指针,sum += gas[j] – cost[j] (从j站加了油,再算上从i开始走到j剩的油,走到j+1站还能剩下多少油)
  2. 如果sum < 0,说明从i开始是不行的。那能不能从i..j中间的某个位置开始呢?既然i出发到i+1是可行的, 又i~j是不可行的, 从而发现i+1~ j是不可行的。
  3. 以此类推i+2~j, i+3~j,i+4~j 。。。。等等都是不可行的
  4. 所以一旦sum<0,index就赋成j + 1,sum归零。
  5. 最后total表示能不能走一圈。

以上做法,其实是贪心的思想:

也就是说brute force的解是 : 一个一个来考虑, 每一个绕一圈, 但是 实际上 我们发现 i - j不可行 直接index就跳到j+1, 这样周而复始,很快就是绕一圈 就得到解了。

算法证明:

1. 我们要证明当total > 0的时候,我们一定存在一个点,从它开始,可以绕一圈。

证明以下设定:

我们假定对任意i, j (i: 0 ~ len-1, j: 0 ~ len-1),我们寻找sum =  Σ (gas[k]-cost[k]) (k 从i到j) ,使sum 最大。我们从i出发,一定可以绕一圈。

i x x x x j x x x x m x

(1)假定存在这个一个m点,从i点出发,到m点会total(i-m) < 0. 也就是说从i出发不可以走完全程。

=> 因为Total > 0 而 total(i-m)<0 ,则必然 total ((m+1) ~ (i-1)) > 0 ,那么我们可以得出total ((m+1) ~ j) > total(i-j),与total(i-j)是最大sum相违背。

=> 根据反证法,上述推定不能成立。所以不会存在这样一个m点,使total(i-m) < 0。也就是说从i出发,我们可以跑完全程。

2. 从1中我们可以看到,只要找到这样一个i-j区间,我们就能使汽车从i点出发,能够跑完全程。按照我们目前使用的算法,只要找到任何一个负区间,我们就丢弃,向下一个区间寻找,这其实就是找最大sum的算法。(因为前面如果是负区间你可以不加他们)最后得到的index实际上就是i (j我们并没有计算,实际上再从0 的index往后寻找一些正的station加上即是j的边界)。

所以从index出发汽车一定可以跑完一圈。另外,这样的解应该不止一个,在i-j之间,从i到n(n在i-j之间)都是可能的解。

实际上只要使total(n~j) >= -total(j+1 ~ i-1)即可, 同样假设假定存在这个一个m点,从n点出发,到m点会total(n-m) < 0. 则因为total(n~j) >= -total(j+1 ~ i-1),同样可以推出total ((m+1) ~ (i-1)) > 0,与以上证明类似,同样会推翻题设。

例如:total(n~j) = 10, total(j+1 ~ i-1) = -9,如果total(n-m)= -1 ,则total ((m+1) ~ (i-1)) = 2 > 0

3. 总结:从i到m只要满足total(n~j) >= -total(j+1 ~ i-1)的点,都是可能的可以出发的点

 public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas == null || cost == null || gas.length == 0 || cost.length == 0) {
// Bug 0: should not return false;
return -1;
} int total = 0;
int sum = 0; int startIndex = 0; int len = gas.length;
for (int i = 0; i < len; i++) {
int dif = gas[i] - cost[i];
sum += dif; if (sum < 0) {
// Means that from 0 to this gas station, none of them can be the solution.
startIndex = i + 1; // Begin from the next station.
sum = 0; // reset the sum.
} total += dif;
} if (total < 0) {
return -1;
} return startIndex;
}
}

GITHUB:

https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/greedy/CanCompleteCircuit.java

LeetCode: Gas Station 解题报告的更多相关文章

  1. 【LeetCode】Gas Station 解题报告

    [LeetCode]Gas Station 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/gas-station/#/descr ...

  2. 【leetCode百题成就】Gas Station解题报告

    题目: There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. ...

  3. [LeetCode] 134. Gas Station 解题思路

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...

  4. LeetCode: Combination Sum 解题报告

    Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Questi ...

  5. [leetcode]Gas Station @ Python

    原题地址:https://oj.leetcode.com/problems/gas-station/ 题意: There are N gas stations along a circular rou ...

  6. [LeetCode] Gas Station 加油站问题

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...

  7. [LeetCode] Gas Station

    Recording my thought on the go might be fun when I check back later, so this kinda blog has no inten ...

  8. 【LeetCode】Permutations 解题报告

    全排列问题.经常使用的排列生成算法有序数法.字典序法.换位法(Johnson(Johnson-Trotter).轮转法以及Shift cursor cursor* (Gao & Wang)法. ...

  9. [LeetCode] Gas Station,转化为求最大序列的解法,和更简单简单的Jump解法。

    LeetCode上 Gas Station是比较经典的一题,它的魅力在于算法足够优秀的情况下,代码可以简化到非常简洁的程度. 原题如下 Gas Station There are N gas stat ...

随机推荐

  1. 阿里面试的一点感受 阿里ali片式经历和面试题

    阿里面试的一点感受 <!-- [废话开始] 百度实习三个月,明天就要离职了,感觉还挺开心的,同事们都很照顾我,Boss也比较欣赏我,我很满足了.掐指一算,这大四其实也没几个月了,同事们都在感叹大 ...

  2. ROS学习(十)—— 使用rosed编辑ROS中的文件

    一.rosed 1.作用: 直接编辑一个文件而不需要打开完整路径名 2.语法: rosed [package_name] [filename] 3.如果不知道编译哪个文件名,可以使用tab进行查询 r ...

  3. Android MD5校验码的生成与算法实现

    在Java中,java.security.MessageDigest (rt.jar中)已经定义了 MD5 的计算,所以我们只需要简单地调用即可得到 MD5 的128 位整数.然后将此 128 位计 ...

  4. block(八)作用域

    //闭包 NSString* s =@"123"; void (^block)() = ^() { NSLog(@"%@",s); }; block();// ...

  5. block(六)循环引用-b

    在ARC与非ARC环境下对block使用不当都会引起循环引用问题,一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身,简单说就是self.theBloc ...

  6. 代码管理(二)sourcetree 安装与使用

    一 .SourceTree简介 SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端,拥有可视化界面,容易上手操作.同时它也是Mercurial和Subve ...

  7. QQMacMgr for Mac(腾讯电脑管家)安装

    1.软件简介    腾讯电脑管家是 macOS 系统上一款由腾讯公司带来到的安全管理软件.功能有垃圾清理.软件仓库.小火箭加速和防钓鱼等.而在视觉 UI 上,导入星空概念,操作过场动画全部以星空为题材 ...

  8. 【C语言】指针数组

    题目:编写UNIX程序sort的简化版本,该程序按字母顺序对由文本行组成的集合进行排序. 思路:我们引入指针数组处理这种问题.如果待排序的文本行首尾相连地存储在一个长字符数组中,那么每个文本行可通过指 ...

  9. apktool 在mac下的使用 -反编译安卓apk文件

    1.下载apktool 点击这里下载 ,里面有两个文件,一个是.jar,一个是自己写的脚本.sh 注:最新的apktool.jar 文件可以点击这里下载 .sh脚本是自写脚本可不用更新最新,下载的ja ...

  10. 转 redis 锁

    原文链接: http://www.promptness.cn/article/34 前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的 ...