[leetcode]Gas Station

此题难。我的解法采用的是O(n)的算法,就是两个指针,end向右走,如果可以,继续向右走,如不行,start向左走。这里的关键是,如果从start走到end,total是负数,那么从任意一个中间的节点出发到end,仍然不可行。因为按照这个走法,从start到中间任何一个节点,total都是正数;有这个正数加成到达end尚且是负数,从中间节点直接走更是不行。

写起来也不容易,length为1以及(gas-cost)全是负数的情况不好处理,后来发现加一个valid的boolean标签就可解决了。代码中start表示起始点,end表示下一个要判断的点。

我的代码是用while(true) + break实现的,也可以用i来表示下一个要更新gas的点是end还是start,类似:http://blog.csdn.net/fytain/article/details/12191103

public class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int start = 0;
        int end = 0;
        int len = gas.length;
        int total = 0;
        boolean valid = false;        
        while (true)
        {
            if (total + gas[end] - cost[end] >= 0)
            {
                total += (gas[end] - cost[end]);
                end = (end + 1) % len;
                valid = true;
                if (start == end) break;
            }
            else
            {
                start = (start + len - 1) % len;
                valid = false;
                if (start == end) break;
                total += (gas[start] - cost[start]);
            }
        }
        if (valid) return start;
        else return -1;
    }
}

然后在discuss里面有个比较巧妙的算法:它基于两点,1. 如果total>0,那么一定有解(需证明);2. 只要记录从目前到结尾的sum为正数的节点就行;

int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
  int sum = 0;
  int total = 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;
}

第二刷,写的简单了点。一是理解了只要能够最终total>=0,说明总能找到一个点,能够走完(否则就平移可以了),而是开始的点是一个转折点,就是之前的那个点是最小值了。

class Solution {
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        int start = -1;
        int size = gas.size();
        int remaining = 0;
        int min_val = 0;
        int min_idx = -1;
        bool hasSolution = false;
        for (int i = 0; i < size; i++) {
            remaining = remaining + gas[i] - cost[i];
            if (remaining >= 0) {
                hasSolution = true;
            } else {
                hasSolution = false;
                if (remaining < min_val) {
                    min_val = remaining;
                    min_idx = i;
                }
            }
        }
        if (!hasSolution) {
            return -1;
        } else {
            return (min_idx + 1) % size;
        }
    }
};

  

posted @ 2013-10-08 23:55  阿牧遥  阅读(632)  评论(0编辑  收藏  举报