Java描述 LeetCode,134. Gas Station 加油站问题

本文介绍了一道关于贪心算法的问题——环形路线上的加油站。当所有加油站的汽油总量小于成本总和时,无法完成一圈旅行。通过分析,我们可以从任意一站出发,如果能到达下一站,则继续前行,否则更新起点。最终找到可以从某个起点出发完成一圈旅行的起点,否则返回-1。提供的代码实现了一个简单的贪心策略来解决此问题,时间复杂度为O(n)。

大家好,我是河海哥,专注于后端,如果可以的话,想做一名code designer而不是普通的coder,一起见证河海哥的成长,您的评论与赞是我的最大动力,如有错误还请不吝赐教,万分感谢。一起支持原创吧!纯手打有笔误还望谅解。

1-1:题目

There are n gas stations along a circular route, where the amount of gas at the ith station is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from the ith station to its next (i + 1)th station. You begin the journey with an empty tank at one of the gas stations.

Given two integer arrays gas and cost, return the starting gas station’s index if you can travel around the circuit once in the clockwise direction, otherwise return -1. If there exists a solution, it is guaranteed to be unique

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.

Constraints:

gas.length == n
cost.length == n
1 <= n <= 105
0 <= gas[i], cost[i] <= 104

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/gas-station

1-2:idea

这道题我自己只会写暴力解法,看完别人的题解后,主要还是整理以及记录。首先有一点是可以想到的,就是如果所有的gas之和<cost之和,那么肯定是不够的。这是全局上看,那么我们再从局部上看,假设我们从某一点i开始出发,到达下一个加油站i+1的条件就是gas[i] > cost[i],这是一个局部,所以根据这个局部,想到达i+2就得,gas[i] - cos[i] + gas[i+1] > cos[i+1],那么一直递推下去,如果出现了小于的情况,就到不了下一个站点,并且![i~i+x]这个区间范围内所有的站点作为起始站点都到不了,牛批就牛批在这句话上。为什么呢?设到达下一个站点的剩余是gas[i]-cos[i] = xi,eg. x1+x2+x3<0,也就是第3站到第4站到时候油不够了,已知x1>0(如果x1不大于0就到不了第2站),x1+x2>0,证明x2+x3<0.很容易证明,因为x1+x2+x3<0且x1>0。所以x2+x3<0,从x2开始也到不了x4的位置。所以出现到不了的情况就果断选择i+1站,继续走。

1-3:代码

public int canCompleteCircuit(int[] gas, int[] cost) {
    int n = gas.length;
    int[] remnant = new int[n];
    int sum = 0;
    for (int i = 0; i < n; i++) {
        remnant[i] = gas[i] - cost[i];
        sum += remnant[i];
    }

    if (sum < 0) {
        return -1;
    }

    int totalRemnant = 0;
    int start = 0;
    for (int i = 0; i < n; i++) {
        totalRemnant += remnant[i];
        if (totalRemnant < 0) {
            start = i + 1;
            totalRemnant = 0;
        }
    }
    return start;
}

优化下:

public int canCompleteCircuit2(int[] gas, int[] cost) {
    int n = gas.length;
    int sum = 0;

    int curTotalRemnant = 0; // 当前循环内的总剩余
    int start = 0;
    for (int i = 0; i < n; i++) {
        int remnant = gas[i] - cost[i];
        sum += remnant;
        curTotalRemnant += remnant;
        if (curTotalRemnant < 0) {
            start = i + 1;
            curTotalRemnant = 0;
        }
    }

    if (sum < 0) {
        return -1;
    }
    return start;
}

时间复杂度O(n^2),空间复杂度O(n)。
这里面有一个问题,为什么只要[start:n]这部分的和>=0就可以了呢?考考你,哈哈哈,这是我自己想到的,是这样的这里用sum控制了整个的和,请看下面的图。
在这里插入图片描述

1-4:总结

这个贪心,我能说啥,妙哇妙哇!哈哈哈哈,继续加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

河海哥yyds

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值