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 };
  • 相关阅读:
    java_泛型
    java工具类Collections
    Map集合的遍历
    集合元素顺序的实现
    apk比较版本大小
    存储过程与SQL语句怎么选择
    线程协作-生产者/消费者问题
    线程中断、线程让步、线程睡眠、线程合并
    如何将字符串去重复demo工具
    JavaScript 中的函数介绍
  • 原文地址:https://www.cnblogs.com/huxiao-tee/p/4227440.html
Copyright © 2011-2022 走看看