20. Candy && Gas Station

Candy

There are N children standing in a line. Each child is assigned a rating value. 

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

What is the minimum candies you must give?

分析: 主要问题是可以从左升序或者从右升序,如何取大值。

方法一:从左从右分别计算一次,对值校正。并计算出最大值。要保存中间初步的值,空间复杂度:O(n)

class Solution {
public:
    int candy(vector<int> &ratings) {
        int n = ratings.size();
        if(n == 0) return 0;
        int totalCandy = 0;
        int *getCandy = new int[n];
        getCandy[0] = 1;
        for(int i = 1; i < n; ++i) 
            if(ratings[i] > ratings[i-1]) getCandy[i] = getCandy[i-1] + 1;
            else getCandy[i] = 1;
        totalCandy += getCandy[n-1];
        for(int i = n-1; i > 0; --i) {
            if(ratings[i-1] > ratings[i]) getCandy[i-1] = max(getCandy[i-1], getCandy[i]+1);
            totalCandy += getCandy[i-1];
        }
        delete[] getCandy;
        return totalCandy;
    }
};

方法二:从一个方向(此题从左),设置两个变量,通过计算升序长度,降序长度确定精确值。空间复杂度:O(1)

class Solution {
public:
    int candy(vector<int> &ratings) {
        int LA = 0, LD = 0; // 利用降序长度和升序长度,来求结果。
        bool decend = false;
        int totalCandy = ratings.size();
        for(int i = 1; i < ratings.size(); ++i) {
            if(ratings[i-1] < ratings[i]) {
                if(LA == 0 || decend == true) LA = 2;//考虑情况:之前为降序,重新设置升序长度
                else ++LA;
                LD = 0; decend = false; //升序时不需要知道之前降序长度。
                totalCandy += (LA - 1);
            }else if(ratings[i-1] > ratings[i]) {
                decend = true;
                if(LD == 0) LD = 2;
                else ++LD;
                if(LD <= LA) totalCandy += (LD - 2);
                else totalCandy += (LD - 1);
            }else {
                LA = LD = 0; // 出现相同字符,则从第二个重复字符重新开始
            }
        }
        return totalCandy;
    }
};

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.

方法一: 直接计算。(752ms)

class Solution {
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        int n = gas.size();
        if(n == 1) return gas[0] >= cost[0] ? 0 : -1;
        int tank = 0;
        for(int i = 0; i < n; ++i) {
            int j = i;
            for(; j < n; ++j) {
                tank += gas[j];
                if(tank < cost[j]) break;
                tank = tank - cost[j];
            }
            if(j == n) {
                for(j = 0; j < i; ++j) {
                    tank += gas[j];
                    if(tank < cost[j]) break;
                    tank = tank - cost[j];
                }
                if(j == i) return i;
            }
            tank = 0;
        }
        return -1;
    }
};

方法二:计算出每个站的油余量:(即从该站开始到下一站,还能剩余的油),将负数或者之前为非负数的值剔除。(20ms)

bool judge(int s, int e, int& cnt, vector<int> &gas) {
    for(int j = s; j < e; ++j) {
        cnt += gas[j];
        if(cnt < 0) return false;
    }
    return true;
}
class Solution {
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        int count = 0;
        for(int i = 0; i < gas.size(); ++i) gas[i] -= cost[i];
        for(int i = 0; i < gas.size(); ++i) {
            if(gas[i] < 0) continue;
            else if(i > 0 && gas[i-1] >= 0) continue;
            if(judge(i, gas.size(), count, gas) && judge(0, i, count, gas)) return i;
            count = 0;
        }
        return -1;
    }
};
原文地址:https://www.cnblogs.com/liyangguang1988/p/3902305.html