zoukankan      html  css  js  c++  java
  • 【Leetcode】【Medium】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.

    解题思路1,o(n):

    选择gas[0]和cost[0]作为起始点,设current_gas_left表示当前剩余的汽油量,则初始current_gas_left = gas[0] - cost[0];

    ①如果gas[0] - cost[0] < 0,说明此站不是起点。但是数组中至少存在一点i,以i为起始,在经历0点时,current_gas_left不为负,

    因此想象数组是一个圈,从0向前(n-1,n-2,...)寻找,即current_gas_left += gas[i] - cost[i],i从n-1取值,不断递减。

    直到累加到current_gas_left不为负,或者i = 0,停止。

    ②如果gas[0] - cost[0] >= 0,或者经历了第①步,current_gas_left不为负后,继续计算后面的加油站。累加current_gas_left += gas[j] - cost[j],j从1取值,不断递增。

    若累加过程中current_gas_left再次出现负值,则继续采用第①步的做法。最终当j <= i时,循环累加停止。

    此时如果current_gas_left为负,说明不存在符合条件的加油站。如果不为负,则i即为满足条件的加油站起点。

    代码如下:

     1 class Solution {
     2 public:
     3     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
     4         int n = gas.size();
     5         int ind_front = n-1;
     6         int ind_back = 1;
     7         
     8         int station_cost = gas[0] - cost[0];
     9         
    10         if (n == 1) 
    11             return station_cost >= 0 ? 0 : -1; 
    12         
    13         while (ind_front >= ind_back) {
    14             if (station_cost < 0) {
    15                 station_cost += gas[ind_front] - cost[ind_front];
    16                 ind_front--;
    17                 continue;
    18             }
    19             
    20             if (station_cost >= 0) {
    21                 station_cost += gas[ind_back] - cost[ind_back];
    22                 ind_back++;
    23                 if (ind_back == n) 
    24                     return 0;
    25             }
    26         }
    27         
    28         return station_cost >= 0 ? ind_back : -1;
    29     }
    30 };

    解题思路2,o(n):

    将所有加油站gas[i]和cost[i]想象合并成一个数组station[i],station[i]代表汽车行驶至此加油站时,将要支付的开销。

    那么station[0]至station[n-1]的值,以加油站为x轴,以开销累加值作为y轴,可以在数轴上画一个折线(如下图)。不论从哪个station开始画起,折线的走势不会改变,只是在x轴上方和下方的比例会有变化。

    如果只有唯一一个加油站能满足行驶一圈的话,那么一定是从折线的最低处的加油站,因为如果从那里作为起点,不管折线走势如何下降,current_gas_left总能保持大于等于0;

    如何从任意一点找到曲线走势的最低点?只需要从任一加油站开始累加其开销值(gas[i] - cost[i]),记录累加的最小值,出现最小值的点就是曲线走势的最低点;

    如果最终all gases > all costs,则加油站起始点就在出现最小值的下一个加油站。

    代码:

     1 class Solution {
     2 public:
     3     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
     4         int current_gas_left = 0;
     5         int lowest_station = -1;
     6         int min = 0;
     7         
     8         for (int i = 0; i < gas.size(); ++i) {
     9             current_gas_left += gas[i] - cost[i];
    10             if (current_gas_left < min) {
    11                 min = current_gas_left;
    12                 lowest_station = i;
    13             }
    14         }
    15         
    16         if (current_gas_left >= 0)
    17             return lowest_station + 1;
    18         else
    19             return -1;
    20     }
    21 };
  • 相关阅读:
    MySQL-基本sql命令
    Java for LeetCode 203 Remove Linked List Elements
    Java for LeetCode 202 Happy Number
    Java for LeetCode 201 Bitwise AND of Numbers Range
    Java for LeetCode 200 Number of Islands
    Java for LeetCode 199 Binary Tree Right Side View
    Java for LeetCode 198 House Robber
    Java for LeetCode 191 Number of 1 Bits
    Java for LeetCode 190 Reverse Bits
    Java for LeetCode 189 Rotate Array
  • 原文地址:https://www.cnblogs.com/huxiao-tee/p/4227440.html
Copyright © 2011-2022 走看看