【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 ...
随机推荐
- 如何使用Vbox添加虚拟机
简介 :vbox是oracle旗下的一个免费的虚拟机软件. 个人感觉操作方便,至少比VM要好用的多. 如果有已经制作好的 点击下一步: 下一步 找到之后 创建 look
- Search for a Range [LeetCode]
Given a sorted array of integers, find the starting and ending position of a given target value. You ...
- 【转载】Gambit使用教程
第一章 Gambit使用 Gambit介绍 网格的划分使用Gambit软件,首先要启动Gambit,在Dos下输入Gambit <filemane>,文件名如果已经存在,要加上参数-old ...
- js首字母大写--单个单词的处理方式
var operate2='OR'; for (var j = 0, len = operate1.length; j< len; j++) { //获得unicode码 var ch2 = o ...
- js在前端获取在本地上传图片的尺寸
var MyTest = document.getElementById("upload_img").files[0];var reader = new FileReader(); ...
- EF 7 Code First
加载方式三种 1. Eager Loading 2. Lazy Loading 3.Explicit Loading 使用EF在与关系型数据库的交互中不可避免地需要加载数据,如何加载数据变得至关重要. ...
- charCodeAt 和 fromCharCode
1.charCodeAt() 定义和用法 charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数. 方法 charCodeAt() 与 ...
- 如何使用Weave以及Docker搭建Nginx反向代理/负载均衡服务器
Hi, 今天我们将会学习如何使用 Weave 和 Docker 搭建 Nginx 的反向代理/负载均衡服务器.Weave 可以创建一个虚拟网络将 Docker 容器彼此连接在一起,支持跨主机部署及自动 ...
- 如何在 Arch Linux 中安装 DNSCrypt 和 Unbound
DNSCrypt 是一个用于对 DNS 客户端和 DNS 解析器之间通信进行加密和验证的协议.它可以阻止 DNS 欺骗或中间人攻击. DNSCrypt 可用于大多数的操作系统,包括 Linux,Win ...
- JMeter常用函数整理
"_csvRead"函数 csvRead函数是从外部读取参数,csvRead函数可以从一个文件中读取多个参数. 下面具体讲一下如何使用csvread函数: 1.新建一个csv或者t ...