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的更多相关文章

  1. 【LeetCode练习题】Gas Station

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

  2. 【LeetCode OJ】Interleaving String

    Problem Link: http://oj.leetcode.com/problems/interleaving-string/ Given s1, s2, s3, find whether s3 ...

  3. 【LeetCode OJ】Reverse Words in a String

    Problem link: http://oj.leetcode.com/problems/reverse-words-in-a-string/ Given an input string, reve ...

  4. 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 ...

  5. 【LeetCode OJ】Validate Binary Search Tree

    Problem Link: https://oj.leetcode.com/problems/validate-binary-search-tree/ We inorder-traverse the ...

  6. 【LeetCode OJ】Recover Binary Search Tree

    Problem Link: https://oj.leetcode.com/problems/recover-binary-search-tree/ We know that the inorder ...

  7. 【LeetCode OJ】Same Tree

    Problem Link: https://oj.leetcode.com/problems/same-tree/ The following recursive version is accepte ...

  8. 【LeetCode OJ】Symmetric Tree

    Problem Link: https://oj.leetcode.com/problems/symmetric-tree/ To solve the problem, we can traverse ...

  9. 【LeetCode OJ】Binary Tree Level Order Traversal

    Problem Link: https://oj.leetcode.com/problems/binary-tree-level-order-traversal/ Traverse the tree ...

随机推荐

  1. 笔记3:关于VBS整人代码的浅谈

    今天又看到有人在群里刷屏了.就想到了以前玩过的发QQ骚扰信息程序了.其实蛮简单的 和网上很多的整人代码差不多 一.直接在网上搜索“VBS整人代码”,然后找到有用的代码复制着. ps:在网上有很多有意思 ...

  2. 20145236 《Java程序设计》 第6周学习总结

    20145236 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入/输出 InputStream与OutputStream 串流设计的概念 Java将输入/输出抽象化为串 ...

  3. grease monkey setTimeout

    在grease monkey中要使用如下方法进行setTimeout var f = function(){alert(1); setTimeout(f,100); } var inst=setTim ...

  4. windows下捕获dump之Google breakpad_client的理解

    breakpad是Google开源的一套跨平台工具,用于dump的处理.很全的一套东西,我这里只简单涉及breakpad客户端,不涉及纯文本符号生成,不涉及dump解析. 一.使用 最简单的是使用进程 ...

  5. Java:数组

    数组 数组是一种引用数据类型(所以才会看到 new int[]),数组的长度初始化完成后是固定的.在内存中初始化数组后的空间就固定下来,即便数组中的内容被清空了,但在内存中占有的空间保留了下来,依然是 ...

  6. Html11.09CSS层叠样式表内容整理

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. PowerMock.expectNew(Class<T> type, Class<?>[] parameterTypes, Object... arguments)

    1:PowerMock.expectNew(Class<T> type, Class<?>[] parameterTypes, Object... arguments) 如果你 ...

  8. cmd命令行中的errorlevel和延迟赋值

    最近用到了命令行,一点心得: 1.errorlevel返回的确实是上一条命令的返回值,但不同命令的表现完全不同.比如: dir echo %errorlevel% //显示0 dir aldkalf ...

  9. CIO谈:基于K2 BPM平台怎么做报销?

    即时!可视!可控!高效! 面对报销系统四大业务目标,有一个对策——用K2! 演讲人:沈明 大鹏天然气CIO 查看完章分享内容请关注K2官方微信

  10. 全国行政区划代码(json对象版)

    var area = {"110000":"北京市","110100":"北京市","110101" ...