我是靠谱客的博主 尊敬白开水,最近开发中收集的这篇文章主要介绍Gas Station (环形加油站),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目:有n个加油站首尾相连成一个圆,已知每个加油站的油量,以及从第i个加油站到第i+1个加油站需消耗的油量,问:能否开车从某个加油站出发,循环一圈又回到起点,如果可以返回出发的起点(车的邮箱容量是无限的)。


此题目来自于leetcode,其原文地址为:https://oj.leetcode.com/problems/gas-station/


此解决方法为自己原创,目前在网上也没有搜索到类似的。

算法时间复杂度为O(n),每个加油站只访问一次。 和网上看到的优雅方案(附后)不差上下。呵呵,纯粹个人感觉。


class Solution {
public:
int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
int start = gas.size()-1;
int end = 0;
int sum = gas[start] - cost[start];
while (start > end) {
if (sum >= 0) {
sum += gas[end] - cost[end];
++end;
}
else {
--start;
sum += gas[start] - cost[start];
}
}
return sum >= 0 ? start : -1;
}
};

代码提交到leetcode上,已经被Accepted了。


算法思路为:

1.  任取一个加油站,作为起点start,然后往前一直开,直到油不够。未能到达之站,记为end。

2.  此时,说明start不适合作起点站。则偿试以start的前面一站作为起点,并更新start,再次偿试,看能否开到站点end。

3.   如果不能开到站点end,说明此站也不合适,继续步骤2.

4.   如果能开到站点end,则继续往前开。直到油不够,并更新end指向此未到之站。继续步骤2.

5.   重复下去,直到start和end相遇。

 

在实现在,我将最后一个站点作为start,可以省去一个取模超作,即end前进可以简单的写作++end,而start后退可以简单的写作—start。

省去了写成 end = (end + 1)%N;  start =(start + N -1)%N;

 



此处贴上在网上看到的优雅方案,供大家比较。

public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
// Note: The Solution object is instantiated only once and is reused by each test case.
int N = gas.length, startIndex = -1;
int sum = 0, total = 0;
for(int i = 0; i < N; i++){
sum += (gas[i] - cost[i]);
total += (gas[i] - cost[i]);
if(sum < 0){
startIndex = i;
sum = 0;
}
}
return total >= 0 ? startIndex + 1 : -1;
}
}

注,此方案为Java语言实现,故接口与上C++实现略有不同。


要透彻理解上面两个算法,最好的方法是先理解下面这道证明题:

一个环形轨道上有n个加油站,所有加油站的油量总和正好够车跑一圈。证明,总能找到其中一个加油站,使得初始时油箱为空的汽车从这里出发,能够顺利环行一圈回到起点。
答案:总存在一个加油站,仅用它的油就足够跑到下一个加油站(否则所有加油站的油量加起来将 不够全程)。把下一个加油站的所有油都提前搬到这个加油站来,并把油已被搬走的加油站无视掉。在剩下的加油站中继续寻找油量足以到达下个加油站的地方,不断合并加油站,直到只剩一个加油站为止。显然从这里出发就能顺利跑完全程。
另一种证明方法:先让汽车油箱里装好足够多的油,随便从哪个加油站出发试跑一圈。车每到一个加油站时,记录此时油箱里剩下的油量,然后把那个加油站的油全部装上。试跑完一圈后,检查刚才路上到哪个加油站时剩的油量最少,那么空着油箱从那里出发显然一定能跑完全程。

 

该证明题摘抄自:http://www.matrix67.com/blog/archives/2671

 

实际上,

前一个算法,是基于证明方法一(合并加油站)上实现的。当然对其作了一点引申。

后一个算法,是基于证明方法二(即找到途中最小剩油量的加站)。当然也是作了一点引申。


作者: 静水流风

最后

以上就是尊敬白开水为你收集整理的Gas Station (环形加油站)的全部内容,希望文章能够帮你解决Gas Station (环形加油站)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部