【LeetCode OJ】Gas Station
Problem link:
http://oj.leetcode.com/problems/gas-station/
We can solve this problem by following algorithm.
CompleteCircuit(gas, cost):
let n be the number of stations
// Check if there exists i such that A[i,n] >= 0
if (sum of gas) > (sum of cost)
return -1 // There is no valid i such that A[i,n] is true // Find the first valid i
i = 0 // start station
tank = 0 // the amount of gas in tank
x = 0 // initially, it is valid to go 0 steps from any station
while x < n:
// Each iteration, we have A[i,x] >= 0, and try to go further
j = (i+x) mod n
// refeul at gas[j] and then use cost[j]
tank += gas[j] - cost[j]
// If tank < 0, it is impossible for car to travel from j to its next station
if tank < 0:
// Set j's next station as the new start station
i = (j+1) mod n
x = 0
tank = 0
else:
x += 1 return i
Correctness
Now, we would prove the algorithm above can solve the problem correctly.
Define E[i,k] which is the amout of gas earned of the car starting from i and going k steps (k <= n)
E[i,k] = 0, if k=0
E[i,k] = gas_earn[i] + gas_earn[i+1] + ... + gas_earn[i+k-1], if 0 < k <= n
where gas_earn[i] = gas[i mod n] - cost[i mod n]
So the problem converts to finding some i such that E[i,k]>=0 for k=0,1,...,n.
Firstly we prove that, there exists some i such that E[i,k] >= 0 for k=0,1,...n if and only if sum(gas[0..n-1]) >= sum(cost[0..n-1]).
(=>) If there exists i such that E[i,k] >= 0, for k=0,1,...n, then we have E[i,n] >= 0, that is
gas_earn[i] + gas_earn[i+1] + ... + gas_earn[i+n-1] >= 0
=> gas_earn[0] + gas_earn[1] + ... + gas_earn[n-1] >= 0
=> sum(gas[0..n-1]) - sum(cost[0..n-1]) >= 0
(<=) Assume sum(gas[0..n-1]) >= sum(cost[0..n01]) and we will show that there must exists i such that E[i,k]>=0 for k=0,...,n by induction.
1) For any circuit of n=1 station, we have
E[0,0] = 0
E[0,1] = gas_earn[0] = gas[0]-cost[0] = sum(gas[0..0]) - sum(cost[0..0]) >= 0
2) Now we already know that for any circuit of (n-1) stations, if sum(gas[0..n-2]) >= sum(cost[0..n-2]) then there must exist i, such that E[i,k]>=0 for k=0,...,n-1.
Consider a circuit of n stations with sum(gas[0..n-1]) >= sum(cost[0..n-1]).
Let j be the station with the minimum gas_earn. If gas_earn[j] >= 0, then every gas_earn is non-negative, we have A[i,n]=true for any i=0,1,..,n-1. So we only consider the case of gas_earn[j] < 0. By merging j and j+1 into one station as j' where gas_earn[j'] = gas_earn[j] + gas_earn[j+1], we can obtain a circuit of (n-1) stations with sum(gas) >= sum(cost). Let E'[i,x] denotethe the amout of gas earned of the car starting from i and going k steps (k <= n-1) in this circuit of (n-1) stations, and d is the number of steps to move from i to j (d > 0 since i != j). Then,
E[i,k] = E'[i,x] >= 0, for k = 0, 1, ..., d-1
E[i,k] = E'[i,k-1] >= 0, for k = d+1, ..., n
Now we only need to check E[i,d],
E[i,d] = gas_earn[i] + gas_earn[i+1] + ... + gas_earn[j-1] + gas_earn[j]
E'[i,d] = gas_earn[i] + gas_earn[i+1] + ... + gas_earn[j-1] + gas_earn[j']
=> E[i,d] = E'[i,d] + gas_earn[j] - gas_earn[j'] = E'[i,d] - gas_earn[j]
=> E[i,d] >= 0 (since E'[i,d]>=0 and gas_earn[j]<0)
By the induction, we can claim that there must exist i such that E[i,k]>=0 for k=0,...,n if sum(gas) >= sum(cost).
Thus, the statement is proved.
Secondly, we will prove that, if E[i,k] >=0 for k=0,1,...,x-1 but E[i,x] < 0, then E[i+j, x-j] < 0 for j = 1, 2, ..., x-1.
According to the definition of E[i,k], we have
E[i,x] = gas_earn[i] + gas_earn[i+1] + ... + gas_earn[i+j] + ... + gas_earn[i+x-1]
E[i,j] = gas_earn[i] + gas_earn[i+1] + ... + gas_earn[i+j-1]
E[i+j,x-j] = gas_earn[i+j] + gas_earn[i+j] + ... + gas_earn[i+j+x-j-1]
So we have:
E[i+j,x-j] = E[i,x] - E[i,j] < 0
This means if we have E[i,k] >=0 for k=0,1,...,x-1 but E[i,x] < 0, then it is impossible for car to go n steps starting from i+1, ..., i+x-1. We only need to check E[i+x, k] for k = 0,...,n.
Python Implementation
class Solution:
# @param gas, a list of integers
# @param cost, a list of integers
# @return an integer
def canCompleteCircuit(self, gas, cost):
# There exists i such that the car staring from i
# can travel around the circuit *if and only if*
# sum(gas) >= sum(cost)
if sum(gas) < sum(cost):
return -1 n = len(gas)
i = 0 # start station, can be selected randomly
t = 0 # the amount of gas in the tank, initially 0
x = 0 # the car go x stations further, initially 0
# x=n means the car travel around and back to the start station
while x < n:
# The car is at station j, going x from i
j = (i+x) % n
# refeul gas[j] and spend cost[j] to get next station
t += gas[j] - cost[j]
# It is impossible to get next station, reset and start from j's next station
if t < 0:
t = 0
x = 0
i = (j+1) % n
else: # or go further
x += 1 return i
【LeetCode OJ】Gas Station的更多相关文章
- 【LeetCode练习题】Gas Station
Gas Station There are N gas stations along a circular route, where the amount of gas at station i is ...
- 【LeetCode OJ】Interleaving String
Problem Link: http://oj.leetcode.com/problems/interleaving-string/ Given s1, s2, s3, find whether s3 ...
- 【LeetCode OJ】Reverse Words in a String
Problem link: http://oj.leetcode.com/problems/reverse-words-in-a-string/ Given an input string, reve ...
- LeetCode OJ:Gas Station(加油站问题)
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...
- 【LeetCode OJ】Validate Binary Search Tree
Problem Link: https://oj.leetcode.com/problems/validate-binary-search-tree/ We inorder-traverse the ...
- 【LeetCode OJ】Recover Binary Search Tree
Problem Link: https://oj.leetcode.com/problems/recover-binary-search-tree/ We know that the inorder ...
- 【LeetCode OJ】Same Tree
Problem Link: https://oj.leetcode.com/problems/same-tree/ The following recursive version is accepte ...
- 【LeetCode OJ】Symmetric Tree
Problem Link: https://oj.leetcode.com/problems/symmetric-tree/ To solve the problem, we can traverse ...
- 【LeetCode OJ】Binary Tree Level Order Traversal
Problem Link: https://oj.leetcode.com/problems/binary-tree-level-order-traversal/ Traverse the tree ...
随机推荐
- isDebugEnabled作用
早上写了日志级别,然后想起在使用的时候经常用isDebugEnabled,一鼓作气.彻底弄懂它: 现象 if (logger.isDebugEnabled()) { logger.debug(m ...
- 20145236 《Java程序设计》第九周学习总结
20145236 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 整合数据库 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API ...
- C++的vector学习abc
开始学习和使用vector了,用到之后再去学似乎神迹的感觉啊,就像跑一下就能给个糖吃哈哈 百度上的六种初始化的方法就不再说了,那些方法都很对. 如果没有值初始化,系统会自行初始化,目前我遇到的是用脚标 ...
- JDE函数--获取当前登录人的描述
业务描述:当前登录人ID为数字,中文姓名保存在描述1字段中 方式: 根据系统变量获取用户的地址号,根据TableIO获取用户描述1.如下图所示: 由于使用AN8时,变量类型不一致,所以使用函数将cha ...
- 25款漂亮的 WordPress 杂志主题
WordPress是一个免费和开源博客工具和一个内容管理系统(CMS)基于 PHP 和 MySQL,它运行在一个 Web 托管服务.每个月的 WordPress 主题是由开发人员,其中用户喜欢使用 W ...
- node.js+WebStorm路径问题
目录路径 :A文件夹下有B.C文件夹和app.js文件.B文件夹下有webserver.js文件等. A B webserver.js ...... C ...... app.js WebStorm配 ...
- C# 检测网络链接
;//Local system uses a modem to connect to the Internet. ; //Local system uses a local area network ...
- 作用域闭包、预解释和this关键字综合题目
var number = 2; var obj = {number : 5, fn1 : ( function() { this.number *= 2; number=number*2; var n ...
- [转载]Android 异步加载解决方案
2013-12-25 11:15:47 Android 异步加载解决方案,转载自: http://www.open-open.com/lib/view/open1345017746897.html 请 ...
- iOS如何生成.a文件
首先来谈谈为何要使用.a文件 Objective-c语言有.h .m 文件组成.静态库可以将 .m文件封装成一个.a文件,第三方应用程序只需要拿到这个.a文件和代码对应的.h文件即可使用静态库中封装的 ...