• [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 }


     

  • 相关阅读:
    LeetCode 252. Meeting Rooms
    LeetCode 161. One Edit Distance
    LeetCode 156. Binary Tree Upside Down
    LeetCode 173. Binary Search Tree Iterator
    LeetCode 285. Inorder Successor in BST
    LeetCode 305. Number of Islands II
    LeetCode 272. Closest Binary Search Tree Value II
    LeetCode 270. Closest Binary Search Tree Value
    LeetCode 329. Longest Increasing Path in a Matrix
    LintCode Subtree
  • 原文地址:https://www.cnblogs.com/agentgamer/p/3661111.html
Copyright © 2020-2023  润新知