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. python中列表的操作

    list1 = ['A' , 'B' , 'C'] list1[0] ; list1[-1] # 取第一个和最后一个元素 list1[ : ] ; list1[ : len(list1)] # 取所有 ...

  2. hdu 1598 find the most comfortable road(枚举+卡鲁斯卡尔最小生成树)

    find the most comfortable road Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  3. hashtable 实现

    #include <stdlib.h> #include <stdio.h> #include <string.h> typedef struct _hashnod ...

  4. 聚类算法:ISODATA算法

    1. 与K-均值算法的比较 –K-均值算法通常适合于分类数目已知的聚类,而ISODATA算法则更加灵活: –从算法角度看, ISODATA算法与K-均值算法相似,聚类中心都是通过样本均值的迭代运算来决 ...

  5. 5月11日 ArrayList集合复习、特殊集合、枚举类型

    一.ArrayList集合复习 //定义 ArrayList al = new ArrayList(); //添加元素 al.Add(); //插入元素 al.Insert(,); //查看个数 in ...

  6. Hyper-V和Virtual PC的不同

    微软在2003年收购了推出了Virtual PC软件的Connectix公司,并在其后推出了Virtual Server服务器虚拟化软件 Hyper-V跟微软自家的Virtual PC.Virtual ...

  7. java面向对象编程——第八章 类的高级概念

    8.1访问修饰符: public:该类或非该类均可访问: private: 只有该类可以访问: protected:该类及其子类的成员可以访问,同一个包中的类也可以访问: 默认:相同数据包中的类可以访 ...

  8. 使用MediaPlayer和SurfaceView播放视频

    使用VideoView播放视频简单.方便,丹有些早期的开发者更喜欢使用MediaPlayer来播放视频,但由于MediaPlayer主要用于播放音频,因此它没有提供图像输出界面,此时 需要借助于Sur ...

  9. BroadcastReceiver的实例----基于Service的音乐播放器之一

    下面的程序开发了一个基于Service的音乐盒,程序的音乐将会由后台运行的Service组件负责播放,当后台的播放状态发生改变时,程序将会通过发送广播通知前台Activity更新界面:当用户单击前台A ...

  10. [示例]NSDictionary编程题-字典的排序应用(iOS4班)

    代码: #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepo ...