Leetcode加油站

时间:2014-05-08 21:24:09

标签: algorithm search

我从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)解决方案吗?

2 个答案:

答案 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;
    }
}