Gas Station(贪心 类似于max subarray)
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 in the clockwise direction, otherwise return -1.
/* 有点类似银行家算法
* 选择一个 gas-cost最大的点作为起点 这样保证当前剩余的油量最多
* */
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
vector<pair<int, int>> start;// left, position
int len=gas.size();
for(int i=0;i<len;i++){
if(gas[i]-cost[i]>=0) start.push_back({gas[i]-cost[i], i});
}
if(start.empty()) return -1;
sort(start.begin(), start.end(), [](pair<int, int> a, pair<int, int> b){ return a.first>b.first;});
for(auto it : start){
int local = it.second, cnt=0, left=0;
while(cnt<len){
if(left+gas[local]-cost[local]<0) break;
left += gas[local]-cost[local];
cnt++;
}
if(cnt==len) return it.second;
}
return -1;
}
};
这也能过。。更好的方法是: 我们首先要知道能走完整个环的前提是gas的总量要大于cost的总量,这样才会有起点的存在。假设开始设置起点start = 0, 并从这里出发,如果当前的gas值大于cost值,就可以继续前进,此时到下一个站点,剩余的gas加上当前的gas再减去cost,看是否大于0,若大于0,则继续前进。当到达某一站点时,若这个值小于0了,则说明从起点到这个点中间的任何一个点都不能作为起点,则把起点设为下一个点,继续遍历。当遍历完整个环时,当前保存的起点即为所求。
这其实是个贪心的策略: 保证遍历到的区间内剩余油量>=0, 如果没有, 就从下一个点作为起点开始。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int start=0, left=0, sum=0;
for(int i=0;i<gas.size();i++){
left += gas[i]-cost[i];
sum += gas[i]-cost[i];
if(left<0){
start = i+1;
left = 0;
}
}
// 如果sum>0, 从start到0 这段肯定是可以, 从0-start这段 由于sum>0, 所以一定能在这段走完
return sum<0 ? -1 : start;
}
};