LeetCode: 134. Gas Station

LeetCode: 134. 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.

解题思路 —— 模拟

根据要求, 依次以每一个 station 作为起点, 模拟整个过程。

优化: 比如,A,B,C,D,E,F,G 几个站, 以 B 站为起点, travel 到 F 站时, 汽油不够。 那么我们就可以确定分别以 B, C, D, E 几个站为起点,都到达不了 F 站。 因为既然 B 站能到达 C, D, E 几个站, 那么到达的时候,汽油量一定是大于等于 0 的。这时候再从 C, D, E 出发,汽油量实际上大于等于直接从这几个站出发的汽油量。因此,既然从 B 站到不了 F 站出发, 那从 C, D, E 出发也到不了 F 站。因此,我们可以直接跳过 C, D, E 这几个站,而直接以 F 站为起点,模拟计算。

AC 代码

未优化代码(Runtime: 298 ms, complexity: O(n^2))

class Solution
{
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) 
    {
        int startStation = -1; // 环绕一周的起点
        int curStation;        // 正在 travel 的 station
        int gasTank;           // gas tank 剩余的 gas

        // 遍历每一个 station 作为起点
        for(size_t i = 0; i < gas.size(); ++i)
        {
            // 初始化: gas tank 剩余 gas 为 0, 当前 station 为出发站 i
            gasTank = 0;
            curStation = i;

            do
            {
                // 加气
                gasTank += gas[curStation];    

                // 前往下一站
                gasTank -= cost[curStation];  
                curStation = (curStation+1) % gas.size();

                // 前往下一站的 gas 不够, 选择下一个 station 作为起点
                if(gasTank < 0)
                {
                    break;
                }
            }while(curStation != i);

            // 如果 curStation 就是起点, 并且 gas tank 剩余的 gas 不为负,表示已成功绕行一周
            if(curStation == i && gasTank >= 0)
            {
                startStation = i;
                break;
            }
        }

        return startStation;
    }
};

优化代码(Runtime: 6ms, complexity: O(n))

class Solution
{
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) 
    {
        int startStation = -1; // 环绕一周的起点
        int travelStation;     // 当前已 travel 的 station 数
        int curStation;        //当前 travel 的 station
        int gasTank;           // gas tank 剩余的 gas

        // 遍历每一个 station 作为起点(直接跳过模拟失败所经历的 station)
        for(size_t i = 0; i < gas.size(); i += travelStation)
        {
            // 初始化: gas tank 剩余 gas 为 0, 当前 station 为出发站 i
            gasTank = 0;
            travelStation = 0;
            curStation = i;

            do
            {   
                // 加气
                gasTank += gas[(curStation)];    

                // 前往下一站
                gasTank -= cost[curStation];  
                curStation = (curStation+1) % gas.size();
                ++travelStation;

                // 前往下一站的 gas 不够, 选择下一个 station 作为起点
                if(gasTank < 0)
                {
                    break;
                }
            }while(curStation != i);

            // 如果 curStation 就是起点, 并且 gas tank 剩余的 gas 不为负,表示已成功绕行一周
            if(curStation == i && gasTank >= 0)
            {
                startStation = i;
                break;
            }
        }

        return startStation;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值