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;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值