加载中...

daily leetcode - gas-station - !

题目地址

https://leetcode.com/problems/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 in the clockwise direction, otherwise return -1.

Note:

  • If there exists a solution, it is guaranteed to be unique.
  • Both input arrays are non-empty and have the same length.
  • Each element in the input arrays is a non-negative integer.

Example 1:

Input:
gas  = [1,2,3,4,5]
cost = [3,4,5,1,2]

Output: 3

Explanation:
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 4. Your tank = 4 - 1 + 5 = 8
Travel to station 0. Your tank = 8 - 2 + 1 = 7
Travel to station 1. Your tank = 7 - 3 + 2 = 6
Travel to station 2. Your tank = 6 - 4 + 3 = 5
Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
Therefore, return 3 as the starting index.

Example 2:

Input: 
gas  = [2,3,4]
cost = [3,4,3]

Output: -1

Explanation:
You can't start at station 0 or 1, as there is not enough gas to travel to the next station.
Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 0. Your tank = 4 - 3 + 2 = 3
Travel to station 1. Your tank = 3 - 3 + 3 = 3
You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3.
Therefore, you can't travel around the circuit once no matter where you start.

思路

这道转圈加油问题不算很难,只要想通其中的原理就很简单。我们首先要知道能走完整个环的前提是 gas 的总量要大于 cost 的总量,这样才会有起点的存在。假设开始设置起点 start = 0, 并从这里出发,如果当前的 gas 值大于 cost 值,就可以继续前进,此时到下一个站点,剩余的 gas 加上当前的 gas 再减去 cost,看是否大于 0,若大于 0,则继续前进。当到达某一站点时,若这个值小于 0 了,则说明从起点到这个点中间的任何一个点都不能作为起点,则把起点设为下一个点,继续遍历。当遍历完整个环时,当前保存的起点即为所求。

关键点解析

代码

解法一:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int total = 0, sum = 0, start = 0;
        for (int i = 0; i < gas.size(); ++i) {
            total += gas[i] - cost[i];
            sum += gas[i] - cost[i];
            if (sum < 0) {
                start = i + 1;
                sum = 0;
            }
        }
        return (total < 0) ? -1 : start;
    }
};

我们也可以从后往前遍历,用一个变量 mx 来记录出现过的剩余油量的最大值,total 记录当前剩余油量的值,start 还是记录起点的位置。当 total 大于 mx 的时候,说明当前位置可以作为起点,更新 start,并且更新 mx。为啥呢?因为我们每次 total 加上的都是当前位置的油量减去消耗,如果这个差值大于 0 的话,说明当前位置可以当作起点,因为从当前位置到末尾都不会出现油量不够的情况,而一旦差值小于 0 的话,说明当前位置如果是起点的话,油量就不够,无法走完全程,所以我们不更新起点位置 start。最后结束后我们还是看 totoa 是否大于等于 0,如果其小于 0 的话,说明没有任何一个起点能走完全程,因为总油量都不够,参见代码如下:

解法二:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int total = 0, mx = -1, start = 0;
        for (int i = gas.size() - 1; i >= 0; --i) {
            total += gas[i] - cost[i];
            if (total > mx) {
                start = i;
                mx = total;
            }
        }
        return (total < 0) ? -1 : start;
    }
};

本文参考自:
https://github.com/grandyang/leetcode/ &
https://github.com/azl397985856/leetcode


标题:daily leetcode - gas-station - !
作者:lonuslan
地址:https://lonuslan.com/articles/2020/07/22/1595413043855.html


评论