Leetcode question group 39 (greedy)

Posted by hillbilly928 on Tue, 14 Dec 2021 05:22:55 +0100

134. Gas stations

There are , N , gas stations on a ring road, of which the , I , gas station has , gas[i] liters of gasoline.

You have a car with unlimited fuel tank capacity. Driving from the i-th gas station to the i+1 , th gas station requires , cost[i] liters of gasoline. You start from one of the gas stations and start with an empty tank.

If you can drive around the loop, return to the number of the gas station at the time of departure, otherwise return to - 1.

Description:

If the question has a solution, the answer is the only answer.
The input arrays are all non empty arrays with the same length.
All elements in the input array are non negative numbers.
Example 1:

Input:
gas  = [1,2,3,4,5]
cost = [3,4,5,1,2]

Output: 3

Explanation:
4 litres of gasoline can be obtained from gas station 3 (index 3). The tank now has = 0 + 4 = 4 litres of petrol
Drive to No. 4 gas station and there is 4 - 1 + 5 = 8 litres of gasoline in the tank
Drive to No. 0 gas station and there is 8 - 2 + 1 = 7 litres of gasoline in the tank
Drive to No. 1 gas station and there is 7 - 3 + 2 = 6 litres of gasoline in the tank
Drive to gas station 2 and there is 6 - 4 + 3 = 5 litres of gasoline in the tank
You need to consume 5 liters of gasoline to drive to gas station 3, which is just enough for you to return to gas station 3.
Therefore, 3 can be the starting index.

analysis:

First, create an array to store the net consumption, that is, gas - cost. If the whole process can be completed, there must be a starting point. Starting from its node, the net consumption in the future is greater than zero. Then we only need to save a starting point. If the net consumption after this starting point is less than zero, we will update this starting point.

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

 135. Distribution of candy

The teacher wants to distribute candy to the children. There are N# children standing in a straight line. The teacher will score each child in advance according to their performance.

You need to help the teacher distribute candy to these children according to the following requirements:

Each child is assigned at least one candy.
Children with higher scores must get more candy than their neighbors on both sides.
So how many candies does the teacher need to prepare at least?

Example 1:

Input: [1,0,2]
Output: 5
Explanation: you can distribute 2, 1 and 2 sweets to the three children respectively.

analysis:

The idea of this topic is similar to 42. Rainwater connection . We first determine an incremental sequence from left to right, and then determine an incremental sequence from right to left. The value of the current node is the maximum value of the two incremental sequences.

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candyVec(ratings.size(), 1);
        for (int i = 1; i < ratings.size(); ++i) {
            if (ratings[i] > ratings[i-1]) candyVec[i] = candyVec[i-1] + 1;
        }
        for (int i = ratings.size()-2; i >= 0; --i) {
            if (ratings[i] > ratings[i+1]) candyVec[i] = max(candyVec[i], candyVec[i+1] + 1);
        }
        int sum = 0;
        for (int num: candyVec) sum += num;
        return sum;
    }
};

 860. Lemonade change

At the lemonade stand, each glass of lemonade costs {5 dollars. Customers line up to buy your products (in the order of bill payment) one cup at a time.

Each customer buys only one glass of lemonade and pays you $5, $10 or $20. You must give each customer the correct change, that is, the net transaction is that each customer pays you $5.

Note that you don't have any change at first.

Give you an integer array bills, where bills[i] is the bill paid by the ith customer. If you can give each customer the correct change, return {true; otherwise, return false.

Example 1:

Input: bills = [5,5,5,10,20]
Output: true
Explanation:
For the first three customers, we charge three five dollar bills in sequence.
At the fourth customer, we charge a $10 bill and return $5.
At the fifth customer, we returned a $10 bill and a $5 bill.
Since all customers get the correct change, we output true.

analysis:

In case of 20 yuan, first find the combination of 10 + 5. If not, find three combinations of 5.  

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        vector<int> have(3, 0);
        for (int i = 0; i < bills.size(); ++i) {
            if (bills[i] == 5) ++have[0];
            if (bills[i] == 10) {
                if (have[0]) { --have[0]; ++have[1]; }
                else return false;
            }
            if (bills[i] == 20) {
                if (have[1] >= 1 && have[0] >= 1) { --have[1]; --have[0]; }
                else if (have[0] >= 3) { have[0]-=3; }
                else return false;
            }
        }
        return true;
    }
};

Topics: Algorithm leetcode greedy algorithm