0
点赞
收藏
分享

微信扫一扫

【leetcode】134. 加油站

🚅【leetcode】134. 加油站


在这里插入图片描述

🚀题目

leetcode原题链接

💥leetcode代码模板

/**
 * @param {number[]} gas
 * @param {number[]} cost
 * @return {number}
 */
var canCompleteCircuit = function(gas, cost) {

};

🚀思路

方法一:暴力

🟡暴力的解法就是遍历所有的加油站,以每一个加油站作为起点,模拟一圈。如果走了一圈到达了起点且中途油量够用那么就返回该起点的索引,全部遍历完都没找到就返回-1。
当然,暴力的时间复杂度是 O ( n 2 ) O(n^2) O(n2),比较耗时,不过用javascript也还能过,没有超时。


方法二:一次遍历

这里参考了leetcode官方的题解,用数学证明来解决,因为有时候直观上并不容易得出某些结论,所以还是得用数学证明。

🟡我们假设从索引x出发最远能到达y,即到达不了y+1,所以油量一定不够,如下式:

∑ i = x y g a s [ i ] < ∑ i = x y c o s t [ i ] \displaystyle\sum_{i=x}^ygas[i] < \displaystyle\sum_{i=x}^ycost[i] i=xygas[i]<i=xycost[i]

既然从x可以到达y,途中必定经过x和y之间的加油站,所以从x出发一定可以到达x和y之间的任意加油站z,用式子表示如下:
∑ i = x z g a s [ i ] > = ∑ i = x z c o s t [ i ] \displaystyle\sum_{i=x}^zgas[i] >= \displaystyle\sum_{i=x}^zcost[i] i=xzgas[i]>=i=xzcost[i]

🔵现在我们想知道的是从x和y之间的任意站点z出发能不能到达y的下一个加油站,直观上感觉从x都到不了y的下一个站点,那么从x和y之间的站点出发油更少,应该更加不能到达。但是我们无法确定这个结论,所以要证明一下.如果我们能证明下式,说明上述结论成立:
∑ i = z y g a s [ i ] < ∑ i = z y c o s t [ i ] \displaystyle\sum_{i=z}^ygas[i] < \displaystyle\sum_{i=z}^ycost[i] i=zygas[i]<i=zycost[i]

如果该结论成立,我们就没有必要像方法一样,以x和y之间的站点为起点来模拟一圈,直接从y的下一个站点去模拟就好。

🟢证明如下

∑ i = z y g a s [ i ] \displaystyle\sum_{i=z}^ygas[i] i=zygas[i] = ∑ i = x y g a s [ i ] \displaystyle\sum_{i=x}^ygas[i] i=xygas[i] - ∑ i = x z − 1 g a s [ i ] \displaystyle\sum_{i=x}^{z-1}gas[i] i=xz1gas[i]
                    < ∑ i = x y c o s t [ i ] \displaystyle\sum_{i=x}^ycost[i] i=xycost[i] - ∑ i = x z − 1 c o s t [ i ] \displaystyle\sum_{i=x}^{z-1}cost[i] i=xz1cost[i]
                    = ∑ i = z y c o s t [ i ] \displaystyle\sum_{i=z}^ycost[i] i=zycost[i]

得证!
🟣所以我们可以优化一下方法一,即遍历加油站,遇到油不够的情况就直接把下一个加油站作为起点遍历。

💻代码

在这里插入图片描述

方法一:暴力

var canCompleteCircuit = function(gas, cost) {
    for(let i = 0 ; i < gas.length ; i++){  // 从索引i出发
        let rest = gas[i] - cost[i] //记录剩余油量
        let index = (i + 1) % gas.length    // 往前走一站
        while(rest > 0 && index !== i){ // 只要还有油且没回到起点
            rest += gas[index] - cost[index]
            index = (index + 1) % gas.length
        }  
        if(rest >= 0 && index === i) return i
    }
    return -1
};

方法二:一次遍历

var canCompleteCircuit = function(gas, cost) {
    const n = gas.length;
    let i = 0;
    while (i < n) {
        let sumOfGas = 0, sumOfCost = 0;
        let cnt = 0;
        while (cnt < n) {
            const j = (i + cnt) % n;
            sumOfGas += gas[j];
            sumOfCost += cost[j];
            if (sumOfCost > sumOfGas) {
                break;
            }
            cnt++;
        }
        if (cnt === n) {
            return i;
        } else {
            i = i + cnt + 1;
        }
    }
    return -1;
};
举报

相关推荐

0 条评论