zoukankan      html  css  js  c++  java
  • [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;
            }
        }
    };
    

      

  • 相关阅读:
    Python爱心动画GIF
    R学习-8.Logic
    R学习-7.Matrices and Data Frames
    R学习-6.Subsetting Vectors
    R学习-5.Missing Values
    R学习-4.Vectors
    R学习-3.sequence of numbers
    R学习-2.Workspace and Files
    R学习-1.Basic Building Blocks
    通过生物学数据预测年龄-1
  • 原文地址:https://www.cnblogs.com/lautsie/p/3358311.html
Copyright © 2011-2022 走看看