我从leetcode看到gas station problem。它可以在O(n)中解决,因为如果从站i开始,并且当到达站j时,没有足够的气体进入j + 1站,那么没有一个站从i到j可以用作起点。在another post中提供了类似的方法。
我认为这个事实适用于假设油箱具有无限存储空间。如果罐的最大存储量(即,如果sum + gas [i]> MAXN,则sum = MAXN,否则sum + = gas [i]在每个站中)怎么办?在这种情况下,不一定是从i到j的站都不能用作起点。那么问题还有O(n)解决方案吗?
答案 0 :(得分:4)
在这种情况下,从i到j的所有站都不能用作起点,这不一定是真的。
这不是真的。制定更多限制不会导致更多可能的起点,这将导致更少。最佳候选起点仍然是原始算法返回的起点。如果在任何一个站点你有充足的气体,并且在你完成一个完整的循环之前你的气体耗尽,那么就没有解决方案了。
让我们假设你在满座汽油的最后一站是第i站,并且在第i + k站用完了汽油。这意味着,在i和i + k站之间,当你到达时,你总是至少有0气体。因此,如果你已经开始使用0气体,那么无论如何你都会在i + k站用完它。如果你从i + k站或之后的任何站开始,你仍然会没有从站i到站i + k的气体。
因此,要解决此问题,首先使用原始算法找到最佳候选站,然后从结果站进行第二轮检查是否可以将其恢复到起点。如果你不能,没有解决方案。
原始问题的最佳解决方案可确保在每个站点都有最大可能的气体。因此,如果该起点导致圆圈成功,那么原始算法返回的所有其他起点也将起作用。
编辑:
要查找其他解决方案,请在canCompleteCircuit(未经测试)之后执行此操作:
int findOtherSolutions(vector<int> &gas, vector<int> &cost, int bestStation, int totalGasLeft) {
int sum = totalGasLeft;
int min = totalGasLeft;
vector<int> solutions;
solutions.push_back(bestStation);
for(int i = bestStation-1; i != bestStation ; --i){
sum -= gas[i]-cost[i];
if(sum <= min){
min = sum;
solutions.push_back(i);
}
if(i==0){
i = gas.size();
}
}
return solutions;
}
请注意,您必须修改canCompleteCircuit以获取剩余气体总量:
int canCompleteCircuit(vector<int> &gas, vector<int> &cost, int &total) {
int sum = 0;
int j = -1;
for(int i = 0; i < gas.size() ; ++i){
sum += gas[i]-cost[i];
total += gas[i]-cost[i];
if(sum < 0){
j=i; sum = 0;
}
}
return total>=0? j+1 : -1;
}
答案 1 :(得分:-1)
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int size = gas.length;
for(int i=0;i<size;i++) {
gas[i] = gas[i] - cost [i];
}
//try to find the start index which has the max addition value
int index = -1;
int maxLeft = -1;
int left = 0;
for(int i=size -1;i>=0;i--){
left +=gas[i];
if(left > maxLeft) {
index = i;
maxLeft = left;
}
}
if(left < 0) index = -1;
return index;
}
}