Java 求解加油站

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 求解加油站相关的知识,希望对你有一定的参考价值。

一、题目

在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。

说明:

  • 如果题目有解,该答案即为唯一答案。
  • 输入数组均为非空数组,且长度相同。
  • 输入数组中的元素均为非负数。

二、题解

暴力解法: 遍历每一个加油站,模拟一圈,如果跑了一圈,没有断油,而且最后油量大于等于0,说明这个起点是可以的。

for 循环适合模拟从头到尾的遍历,而 while 循环适合模拟环形遍历,要善于使用 while

贪心解法:

如果总油量减去总消耗大于等于零那么说明,一定可以跑完一圈,说明各个站点的加油站,剩余油量想加一定是可以大于等于零的

i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,起始位置从i+1算起,再从0计算curSum。


那么为什么一旦[i,j] 区间和为负数,起始位置就可以是j+1呢,j+1后面就不会出现更大的负数?

那么为什么一旦[i,j] 区间和为负数,起始位置就可以是j+1呢,j+1后面就不会出现更大的负数?

如果出现更大的负数,就是更新j,那么起始位置又变成新的j+1了。

而且j之前出现了多少负数,j后面就会出现多少正数,因为耗油总和是大于零的(前提我们已经确定了一定可以跑完全程)。

三、代码

暴力解法:

class Solution 
    public int canCompleteCircuit(int[] gas, int[] cost) 
        int res;
        int index;
        for (int i = 0; i < gas.length; i++) 
            res = gas[i] - cost[i];
            // 环形绕,所以写成这种写法
            index = (i + 1) % gas.length;
            // 如果能循环一周,保持不空油,则 i 点可以当做起点
            while (res >= 0 && index !=i) 
                res += gas[index] - cost[index];
                index = (index + 1) % gas.length;
            
            if (res >= 0) 
                return i;
            
        
        return -1;
    

贪心解法:

class Solution 
    public int canCompleteCircuit(int[] gas, int[] cost) 
        // 记录当前总和
        int curSum = 0;
        // 记录总和
        int totalSum = 0;
        int start = 0;
        for (int i = 0; i < gas.length; i++) 
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            // 如果当前总和小于0,说明当前值及其前的点,都不适合作为起点
            if (curSum < 0) 
                start = i + 1;
                curSum = 0;
            
        
        // 如果总的差值之和小于0,说明无法环绕一周
        if (totalSum < 0) 
            return -1;
        
        return start;
    

四、总结

暴力解法注意,while 的应用,for 循环适合遍历,while 适合环形遍历,以及环形的处理:

index = (index + 1) % gas.length;

贪心解法,局部最优,推出全局最优

以上是关于Java 求解加油站的主要内容,如果未能解决你的问题,请参考以下文章

应用问题求解,加油站有效加油位问题!

贪心算法求解汽车加油问题

数据结构与算法之深入解析“加油站”的求解思路与算法示例

贪心算法--汽车加油问题

空当接龙求解:java版广度优先

贪心算法:汽车加油问题