Leetcode|greedy algorithm [allocation + interval] (135|435|455...)

Keywords: C++ Algorithm leetcode

Greedy Algorithm

The simple understanding is to ensure the local optimization, the local results are irrelevant, and the results are the simple summation of the local optimal results to achieve the global optimization.

assignment problem

455. Distribute cookies [Assign Cookies (Easy)]

Title Description
Suppose you are a great parent and want to give your children some cookies. However, each child can only give one biscuit at most.
For each child I, there is an appetite value g[i], which is the minimum size of biscuits that can satisfy the children's appetite; And every cookie j has a size s[j]. If s[j] > = g[i], we can assign this biscuit j to child I, and the child will be satisfied. Your goal is to meet as many children as possible and output this maximum value.
Input and output samples

  • Example 1
    Input: g = [1,2,3], s = [1,1]
    Output: 1
  • Example 2
    Input: g = [1,2], s = [1,2,3]
    Output: 2
    Explanation:
    You have two children and three cookies. The appetite values of two children are 1 and 2 respectively.
    You have enough cookies and sizes to satisfy all children.
    So you should output 2
    In this example, we can feed two children any combination of [1,2], [1,3] and [2,3].

analysis
The greedy strategy is adopted. According to the meaning of the question, the child with the smallest appetite is the most likely to be full, and the child is given priority; Give the remaining children with the smallest appetite the smallest biscuits that can satisfy their appetite, and repeat the strategy until there are no biscuits.
code

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(),g.end());//Sort the child's appetite
        sort(s.begin(),s.end());//Sort the size of cookies
        int child = 0,cookies = 0;
        //Cycle until there are no cookies and children
        for(child;child<g.size()&&cookies<s.size();cookies++){ 
            if(g[child]<=s[cookies])
                child++;//Number of children satisfied
        }
        
        return child;
    }
};

135. Distribute Candy (Hard)

Title Description
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?
Input and output samples

  • Example 1
    Input: [1,2,2]
    Output: 4
    Explanation:
    You can distribute 1, 2 and 1 candy to the three children respectively.
    The third child only got one candy, which met the above two conditions.

analysis
The greedy strategy is adopted and understood according to the meaning of the question. Since the minimum number of sweets is 1, initialize that the number of sweets of all children is 1 first. After two iterations, traverse from left to right. When the score of the right child is greater than that of the left, the number of sweets of the right child + 1; Traverse from right to left. When the score of the left child is greater than that of the right, and the number of sweets of the left child is not greater than that of the right, the number of sweets of the left child is the number of sweets of the right child + 1.
code

class Solution {
public:
    
  int candy(vector<int>& ratings) {
        int size = ratings.size();
        //Initialize the number of sweets for all children to 1
        vector<int> candy_num(size,1);
        //Only one child
        if(size < 2)
            return size;
        //Traversal from left to right
        for(int i = 1; i < size; ++i){
            //If the score of the child on the right is greater than that on the left, give one more candy
            if(ratings[i] > ratings[i-1])
                candy_num[i] = candy_num[i-1] + 1;
        }
        //Right to left traversal
        for(int i = size - 1; i > 0; --i){
            //If the score of the left child is greater than that of the right, and the number of sweets of the left child is not greater than that of the right, the number of sweets of the left child is equal to the number of sweets of the right child + 1
            if(ratings[i] < ratings[i-1])
                candy_num[i-1] = max(candy_num[i -1], candy_num[i]+1);
        }
    return accumulate(candy_num.begin(),candy_num.end(),0);
    //STD:: aggregate, used for summation, which is more convenient
    }
};

Interval problem

435. Non overlapping intervals (medium)

Title Description
Given a set of intervals, find the minimum number of intervals to be removed so that the remaining intervals do not overlap each other. Note: it can be considered that the end of the interval is always greater than its starting point. The boundaries of intervals [1,2] and [2,3] are "in contact" with each other, but do not overlap each other.
Input n intervals and output the number of intervals to be removed.
Input and output samples

  • Example 1
    Input: [1,2], [2,3], [3,4], [1,3]]
    Output: 1
    Explanation:
    After removing [1,3], the remaining intervals do not overlap.

analysis
Using the greedy strategy, according to the meaning of the question, we can sort the tail of each interval and give priority to the interval with the smallest end and no overlap with the previous interval. According to example 1, after sorting, it should be: [[1,2], [2,3], [1,3], [3,4]. The greedy strategy is: give priority to the interval with the smallest tail and no overlap, [1,2] and [1,3] overlap, so we remove [1,3].
code

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        //Judge whether the interval is empty
        if(intervals.empty())
        {
            return 0;
        }
        //Sort the end of each interval. The sort(a,b,c) condition C returns a bool value.
        sort(intervals.begin(),intervals.end(),[](vector<int>& a,vector<int>& b)
        {
            return a[1]<b[1];//Use two vector arrays to store the end of the interval for sorting.
        });
        int n = intervals.size();
        int t = 0, pre = intervals[0][1];//Select the end of the first interval
        for(int i = 1;i < n;i++)
        {
            if(intervals[i][0] < pre){ //If the section head < the tail of the selected section, the sections overlap
                t++;
            }
            else{
                pre = intervals[i][1];
            }
        }
        return t; 
    }
};

Not finished.

Posted by keyur.delhi on Wed, 01 Dec 2021 06:45:03 -0800