【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 ...
随机推荐
- 笔记3:关于VBS整人代码的浅谈
今天又看到有人在群里刷屏了.就想到了以前玩过的发QQ骚扰信息程序了.其实蛮简单的 和网上很多的整人代码差不多 一.直接在网上搜索“VBS整人代码”,然后找到有用的代码复制着. ps:在网上有很多有意思 ...
- 20145236 《Java程序设计》 第6周学习总结
20145236 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入/输出 InputStream与OutputStream 串流设计的概念 Java将输入/输出抽象化为串 ...
- grease monkey setTimeout
在grease monkey中要使用如下方法进行setTimeout var f = function(){alert(1); setTimeout(f,100); } var inst=setTim ...
- windows下捕获dump之Google breakpad_client的理解
breakpad是Google开源的一套跨平台工具,用于dump的处理.很全的一套东西,我这里只简单涉及breakpad客户端,不涉及纯文本符号生成,不涉及dump解析. 一.使用 最简单的是使用进程 ...
- Java:数组
数组 数组是一种引用数据类型(所以才会看到 new int[]),数组的长度初始化完成后是固定的.在内存中初始化数组后的空间就固定下来,即便数组中的内容被清空了,但在内存中占有的空间保留了下来,依然是 ...
- Html11.09CSS层叠样式表内容整理
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- PowerMock.expectNew(Class<T> type, Class<?>[] parameterTypes, Object... arguments)
1:PowerMock.expectNew(Class<T> type, Class<?>[] parameterTypes, Object... arguments) 如果你 ...
- cmd命令行中的errorlevel和延迟赋值
最近用到了命令行,一点心得: 1.errorlevel返回的确实是上一条命令的返回值,但不同命令的表现完全不同.比如: dir echo %errorlevel% //显示0 dir aldkalf ...
- CIO谈:基于K2 BPM平台怎么做报销?
即时!可视!可控!高效! 面对报销系统四大业务目标,有一个对策——用K2! 演讲人:沈明 大鹏天然气CIO 查看完章分享内容请关注K2官方微信
- 全国行政区划代码(json对象版)
var area = {"110000":"北京市","110100":"北京市","110101" ...