From : https://leetcode.com/problems/gas-station/#
There are N gas stations along a circular route, where the amount of gas at station i is gas[i].
You have a car with an unlimited gas tank and it costs cost[i] of gas to travel
from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
Note:
The solution is guaranteed to be unique.
对于任意加油站 i , 汽车车内在此站的增量为 inc[i] = gas[i]-cost[i] 。
题目就是要找到inc数列中的某个位置 i ,使从这个位置开始,向右(下标增大的方向)求和,和一直非负;如果没有找到, 返回 -1。本题中,如果存在这个下标,那就是唯一的。 本质上,如果inc求和非负,求环状序列的最大子序列和的脚小的下标位置; 否则返回-1。
举例:
gas :2 5 4 2
cost :3 7 1 1
inc :-1 -2 3 1
inc视为环,求和非负, 那么求到最大和子序列为 3,1, 下标为2 。
class Solution {
public:
int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
int len = gas.size();
if(len == 0) return -1;
int sum = 0, index =0, cnt =0;
for(int i=0;i<len;i++) {
gas[i] = gas[i]-cost[i];
sum += gas[i];
}
if(sum < 0) return -1;
// 求环的最大子序列,考虑本题在sum>=0时,只有一个位置满足条件,故只要求那个永远和非负的位置
sum = gas[0];
for(int i=1; i<2*len-1; i++) {
if(sum < 0) {
sum = gas[i%len];
index = i;
cnt = 1;
} else {
sum += gas[i%len];
cnt++;
}
if(cnt == len) break;
}
return index;
}
};推荐:
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas == null || gas.length == 0) {
return -1;
}
int sum = 0, n = gas.length;
for (int i = n - 1; i >= 0; --i) {
sum += (gas[i] = gas[i] - cost[i]);
}
if (sum < 0) {
return -1;
}
int indice = 0, find = 0;
sum = -1;
for (int i = 0; i < n+n-1; ++i) {
if (sum < 0) {
indice = i;
sum = gas[i%n];
find = 1;
} else {
sum += gas[i%n];
++find;
}
if (find == n) {
break;
}
}
return indice;
}
}
思路:
1.假设存在这个位置,那么从这个位置开始,向右累加gas[i]-cost[i],和会一直非负。
2.那么从任意位置出发,累加这个值,当和为负,则表示起始位置没有找对,那么向前找起始位置。
3.如果和为正,那么向右做累加。如果这个位置就是那个我们要找的位置,必然会使之后的和一直为正。
4.当我们对所有位置遍历一次,和为正,那么起始位置就是答案;和为负,说明没有这样的起始位置,返回-1。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
if(gas.size() == 0) return -1;
int start=0, end=0, left=0;
for(int i=0, num=gas.size(), count=0; count<num; count++) {
left += gas[i]-cost[i];
if(left >=0) {
end++;
i = end;
} else {
start = (start+num-1)%num;
i = start;
}
}
return (left>=0)*start-(left<0);
}
};
本文探讨了一种解决环形路线上寻找合适的起点以确保车辆能够完成一圈旅行的问题。通过分析加油站提供的油量与行驶成本之间的关系,提出两种有效算法来确定最佳起点。
995

被折叠的 条评论
为什么被折叠?



