力扣134. 加油站

题目来源(力扣):

https://leetcode.cn/problems/gas-station/solutions/488357/jia-you-zhan-by-leetcode-solution/

题目描述:

环形道路有n个点,第i个点可以获得能量a[i],并且可以消耗能量b[i]到达第i+1个点。
找到一个点作为起点,使得从起点出发可以便利环中的所有节点。如果不存在则返回-1。

基本思路:

贪心,思路类似于 https://www.cnblogs.com/hb-computer/articles/18535226
不存在答案的情况:如果sum(a)<sum(b),则无法找的合法的节点;
否则,至少可以找到一个合法的起点符合题意。

从起点0开始(start=0),每次经过一个节点,就将获取其能量a[i]并且消耗能量b[i],
即tmp+=a[i]-b[i];
如果tmp<0,则说明start开始的位置不能满足题意,更新start=i+1,继续往后更新tmp,直到数组末尾。

即贪心策略:如果i~j累计值sum<0,则起始位置至少为j+1。
对于贪心的证明可以见 https://leetcode.cn/problems/gas-station/solutions/488357/jia-you-zhan-by-leetcode-solution/

代码实现:

class Solution
{
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost)
    {
        int sum = 0;  //用于判断sum(a)与sum(b)的大小
        int len = gas.size();
        int start = 0;
        int tmp = 0;  //过程中的临时累计和
        for (int i = 0; i < len; i++)
        {
            tmp += gas[i] - cost[i];
            sum += gas[i] - cost[i];
            if (tmp < 0)  //tmp任意时刻小于0,说明之前的起点有误,需要进行新的起点尝试
            {
                tmp = 0;
                start = i + 1;
            }
        }
        if (sum < 0)
            return -1;
        return start;
    }
};

时间复杂度

O(n)

补充-另一个思路

《代码随想录》中根据全局最优的思路得到另外一种贪心写法:
从0开始计算累加值sum,过程中的最小值为minn;
(1)如果sum<0,说明无解,返回-1;
(2)如果直到最后都minn>=0,则起点为0;
(3)否则,(minn不清0)从len-1位置向前累加,当minn>=0时,则对应的节点就是起点。
代码如下

class Solution
{
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost)
    {
        int sum = 0;
        int len = gas.size();
        int start = 0;
        int minn = 0;
        // 从0走到末尾
        for (int i = 0; i < len; i++)
        {
            sum += gas[i] - cost[i];
            if (sum < minn)
            {
                minn = sum;
            }
        }
        if (sum < 0)
            return -1; //(1) 能量抵不上消耗
        if (minn >= 0)
            return 0; // (2)过程中无负值,说明节点0作为起点就为答案
        // (3)过程中有负值,则从末尾开始往前,直到tmp>=0
        for (int i = len - 1; i >= 0; i--)
        {
            minn += gas[i] - cost[i];
            if (minn >= 0)
            {
                start = i;
                break;
            }
        }
        return start;
    }
};
posted @ 2024-11-15 14:47  HB_Computer  阅读(22)  评论(0)    收藏  举报