标签:
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]
.
You have a car with an unlimited gas tank and it costs cost[i]
of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station‘s index if you can travel around the circuit once, otherwise return -1.
Note:
The solution is guaranteed to be unique.
思路一:
开始就是模拟从每个加油站出发,看是否可以走一圈,双层循环,结果超时。
其实,如果ABC是连续的三个加油站,如果A可以到达B但到不了C,那么B也到不了C,证明如下:
因为A可以到达B,所以有gas[A] >= cost[A]
因为A不可到达C,所以有gas[A] + gas[B] < cost[A] + cost[B]
所以有gas[B] < cost[B],即B不可到达C。
由以上的结论可知,当本次模拟最终不可到达X时,下一次以X当做起点。
这个问题可以抽象为Maximum Subarray那道题,每一个数据是gas[i] - cost[i],和最大子串的起始位置便是起始加油站,当然,前提是存在解,即全部的加和是大于等于零的,证明如下:
i x x x j x x x m x x x
对于num[i] = gas[i] - cost[i],中的每一个数据,找到和最大子串是从i到j,假设存在一个m点total(i-m)<0,即从i不可到达m的下一个位置。
因为total>0,而total(i-m)<0,所以有total((m+1)-(i-1))>0,那么total((m+1)-j) = total(i-j) + total((m+1)-(i-1)) > total(i-j),这与total(i-j)是最大值相违背。
根据反证法,开始的假设不成立。
1 public int canCompleteCircuit(int[] gas, int[] cost) { 2 if(gas == null || cost == null) 3 return -1; 4 int len = gas.length; 5 int total = 0; 6 int sum = 0; 7 int start = 0; 8 for(int i=0; i<len; i++) { 9 int tmp = gas[i] - cost[i]; 10 sum += tmp; 11 if(sum < 0) { 12 start = i+1; 13 sum = 0; 14 } 15 total += tmp; 16 } 17 if(total < 0) 18 return -1; 19 return start; 20 }
标签:
原文地址:http://www.cnblogs.com/ivanyangzhi/p/4442955.html