zoukankan      html  css  js  c++  java
  • [LeetCode] Gas Station

    Recording my thought on the go might be fun when I check back later, so this kinda blog has no intention to be read by others(its just for recording, not article). but if you insist, hope you enjoy it. if you find me wrong, please let me know, very appreciated!

    Gas Station

    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.

    My first try:

     1 class Solution {
     2 public:
     3     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
     4         int footPrint = 0;
     5         int gasMount = gas[footPrint];
     6         
     7         while (gasMount-cost[footPrint] >= 0){
     8             footPrint = (footPrint+1)% gas.size();
     9             if (footPrint == 0){
    10                 //return to first
    11                 return footPrint;
    12             }
    13             gasMount = gasMount - cost[footPrint] + cost[footPrint];
    14         }
    15         return -1;
    16     }
    17 };

    Test failed on:

    Input: [1,2], [2,1]
    Output: -1
    Expected: 1

    Then I realized that I'v completely underastimate the complexity of this problem(of course). what the problem really want me to provide is a choice on which station to begin with so that we can complete the circuit!
    like the test case above, gas=[1,2] cost=[2,1], then if we start at gas[0] we failed to do circle, but if we choose gas[1] to begin with, we first make to gas[0] left for 1 gas, then we refule at gas[0] to get 2 gas,
    and then we can make it to gas[1], thats complete the circuit, so the program output 1, because this is where we begin with.
    But you may wonder, there might be many choices which satisfy this condition, your right, but the NOTE told us, there is only one :), so with that understanding, I have something to work with. 

      Here I am again, but the problem still not solved:( here is the code:
      My 2nd try:

     1 class Solution {
     2 public:
     3     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
     4         int footPrint = 0;
     5         int gasMount = 0;
     6         
     7         for (int i=0; i<gas.size(); i++){
     8             footPrint = i;
     9             gasMount = gas[footPrint];
    10             
    11             while (gasMount - cost[footPrint] >= 0){
    12                 gasMount -= cost[footPrint];
    13                 footPrint = (footPrint+1)%gas.size();
    14                 gasMount += gas[footPrint];
    15                 if (footPrint == i){
    16                     return footPrint;
    17                 }
    18             }
    19         }
    20         return -1;
    21     }
    22 };

    This is really looks like the anwser, I mean its a naive but worked version. it passed all the test until it meet the very large one....I think there might be thousands of elements in input array...
    and the system throw out the Time Limit Exceeded error. damn! that make things even more complicated! That means this naive solution is not acceptable, we have to do it smart, algorithem is a bitch :p

    And finally, I did not work out this problem, what a shame to faile my first leetcode challenge :( , anyway, I did search for anwsers and I really got some hint, also I stole some idea from others and
    then implemented my own AC version.

    My final anwser:

     1     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
     2         int total=0;
     3         for (int i=0; i < gas.size(); i++){
     4             int j=0;
     5             for (; j < gas.size(); j++){
     6                 total += gas[((i+j)%gas.size())] - cost[(i+j)%gas.size()];
     7                 if (total < 0){
     8                     i +=j;
     9                     total = 0;
    10                     break;
    11                 }
    12             }
    13             if (j==gas.size())return i;
    14         }
    15         return -1;
    16     }

    This is a really nice approach which cost only O(n) time, If you think its O(n^2) by just simply looking at the double for loop, then you are wrong, mind that the j is pushing the i forward.
    whenever total is less then 0, the elements which between i to j is no longer need to be checked again, so we simply skip them, in this way, theres actually only 1 loop occurred during the entire operation.
    the thinking behind this algorithm is called Dynamic Programming, and this problem is very similar to Longest Consecutive Sequence problem, the difference is this one do a circuit.

    For the purpose of enhancing what I'v learned, I decide to write down a snippet of code for solving Longest Consecutive Sequence problem. 

     1 int maxSum(int *a, int len){
     2     int i, sum=0, max=0;
     3     for (i=0;i<len;i++){
     4         if (sum >= 0){
     5             sum += a[i];
     6             if (sum > max){
     7                 max = sum;
     8             }
     9         else{
    10             sum = a[i];
    11         }
    12     }
    13     return max;
    14 }


     

  • 相关阅读:
    yii框架入门学习笔记二 根据数据表创建model类
    mysql数据库操纵类升级版
    yii框架入门学习笔记三 完善登陆功能
    java发送http的get、post请求
    Please ensure that adb is correctly located at 'D:\androidsdkwindows\platf
    CodeIgniter框架入门教程——第一课 Hello World!
    C#正则表达式应用
    common lisp 笔记2 a cd ripper
    javascript的String函数
    修改linux下sudo设置
  • 原文地址:https://www.cnblogs.com/agentgamer/p/3661111.html
Copyright © 2011-2022 走看看