Leetcode 134. 加油站 解题思路及C++实现

本文介绍了两种解决LeetCode第134题的方法。方法一是暴力搜索,通过遍历加油站数组,判断是否有可能形成环形线路。方法二是通过记录剩余油量和出发点,找到油量从负变正的转折点,确保可以完成整个环路。文章提供了详细的解题思路和C++代码实现。

方法一:直接暴力方法

解题思路:

当 gas[i] >= cost[i] 时,这个加油站才可能是个出发点,遍历gas容器(数组),当出现 gas[i] >= cost[i] 时,看看以这个加油站为出发点,是否满足条件,即执行函数whetherEnough,如果满足,就得到结果了,返回索引 i 即可,否则,继续寻找下一个可能的出发点。

在whetherEnough函数中,因为是个环形线路,所以先访问 i 后面的加油站,再访问 i 前面的加油站。中途一旦遇到剩余的油量为负,则这条路不通,返回false。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        //遍历gas和cost,gas[i] >= cost[i]的时候,i才可能为出发的加油站编号
        for(int i = 0; i < gas.size(); i++){
            if(gas[i] >= cost[i]){  //可能是个出发点
                if(whetherEnough(i, gas, cost)) return i;
            }
        }
        return -1;
    }
    
    bool whetherEnough(int n, const vector<int> gas, const vector<int> cost){
        //输入的i为出发站, 
        int i = n;
        int save = 0;
        while(i < gas.size()){
            save += (gas[i] - cost[i]);
            if(save < 0) return false;
            else i++;
        }
        for(int j = 0; j < i; j++){
            save += (gas[j] - cost[j]);
            if(save < 0) return false;
        }
        return true;
    }
};

 

方法二:有点技巧

解题思路:

遍历gas容器(数组),分别要做两件事情:一是用变量save来记录剩余油量;二是要找到油量从负变为正的加油站点,即要用start来记录出发加油站点。

我们思考一下为什么会让出发站点放在中间,就是因为前面的数,gas加起来要小于cost,消耗多于供给。而起点后面的加油站,总供给要多于消耗,这样才能走完整个环路。

如果前面的加油站中,debt累加起来是正值,说明之前记录的start位置没有问题,如果出现了debt为负值,说明前面的加油站供给不足,要更新start变量。

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

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值