C++ LeetCode 134 加油站 三种解法:暴力,贪心

#include 
#include
using namespace std;
#define INT_MAX 2147483647

class Solution
{
public:
    int canCompleteCircuit0(vector& gas, vector& cost) { // 暴力解法
        for (int i = 0; i < cost.size(); i++) {
            int rest = gas[i] - cost[i];        // 记录剩余油量
            int nex = (i + 1) % cost.size();    // nex 是 i 的 下一个位置, 当i为数组末尾索引 size - 1,nex 就是 数组起始坐标 0,
            while (rest > 0 && nex != i) {      // 模拟以i为起点行驶一圈
                rest += gas[nex] - cost[nex];
                nex = (nex + 1) % cost.size();
            }
            if (rest >= 0 && nex == i) return i; // 如果以i为起点跑一圈,剩余油量>=0,返回该起始位置
        }
        return -1;
    }

    int canCompleteCircuit1(vector& gas, vector& cost) { // 贪心解法一
        int curSum = 0;
        int min = INT_MAX; // 从起点出发,油箱里的油量最小值
        for (int i = 0; i < gas.size(); i++) {
            int rest = gas[i] - cost[i];
            curSum += rest;
            if (curSum < min) {
                min = curSum;  
            }
        }
        if (curSum < 0) return -1;  // 情况1  如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的
        if (min >= 0) return 0;     // 情况2  如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。
                                    // 情况3
        for (int i = gas.size() - 1; i >= 0; i--) { // 逆向遍历,和上边的正向遍历,组成环。 如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点刚好(重点:刚好, 贪心)能把这个负数(油箱里的油量最小值)填平。(相当于,能够渡过最艰难的时刻,后边就是一马平川)能把这个负数填平的节点就是出发节点。
            int rest = gas[i] - cost[i];
            min += rest;
            if (min >= 0) {
                return i;
            }
        }
        return -1;
    }

    int canCompleteCircuit(vector &gas, vector &cost) // 贪心解法二  和 上边的 贪心解法一  都会有 用 反正法 证明 逻辑合理
    {
        int curSum = 0;
        int totalSum = 0;
        int start = 0;
        for (int i = 0; i < gas.size(); i++)
        {
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if (curSum < 0)
            {                  // 当前累加rest[i]和 curSum一旦小于0
                start = i + 1; // 起始位置更新为i+1
                curSum = 0;    // curSum从0开始
            }
        }
        if (totalSum < 0)
            return -1; // 说明怎么走都不可能跑一圈了
        return start;
    }
};

int main()
{
    vector gas = {1, 2, 3, 4, 5};
    vector cost = {3, 4, 5, 1, 2};
    Solution sol = *new Solution();
    int res = sol.canCompleteCircuit(gas, cost);
    printf("res: %d\n", res);
    return 0;
}

// 编译:g++ demo.cc -o demo
// 执行: ./demo

参考链接:

【1】贪心算法,得这么加油才能跑完全程!LeetCode :134.加油站

你可能感兴趣的:(leetcode,c++,算法)