Leetcode||Algoritmo guloso [alocação + intervalo] (135|435|455..)

Algoritmo Guloso

Um entendimento simples é que o ótimo local é garantido , os resultados locais são irrelevantes uns para os outros e o resultado é uma soma simples dos resultados ótimos locais para atingir o ótimo global .

problema de distribuição

455. Atribuir Cookies (Fácil)

Título Descrição
Suponha que você seja um ótimo pai e queira dar biscoitos para seus filhos. No entanto, cada criança não recebe mais do que um biscoito.
Para cada criança i, existe um valor de apetite g[i], que é o menor tamanho de biscoito que satisfaz o apetite da criança; e cada biscoito j tem um tamanho s[j]. Se s[j] >= g[i], podemos atribuir este cookie j ao filho i, e este filho ficará satisfeito. Seu objetivo é satisfazer o maior número possível de crianças e produzir esse valor máximo.
Amostras de entrada e saída

  • Exemplo 1
    entrada: g = [1,2,3], s = [1,1]
    saída: 1
  • Exemplo 2
    Entrada: g = [1,2], s = [1,2,3]
    Saída: 2
    Explicação:
    Você tem dois filhos e três biscoitos, e os valores de apetite dos dois filhos são 1,2 respectivamente.
    Você tem biscoitos suficientes em quantidade e tamanho para manter todas as crianças satisfeitas.
    Portanto, você deve produzir 2.
    Neste exemplo, podemos alimentar qualquer uma das três combinações [1,2], [1,3], [2,3] para os dois filhos.

Análise
Adote a estratégia gulosa, de acordo com o significado da pergunta, a criança com menor apetite é a mais fácil de comer, e a criança fica satisfeita primeiro; atribua o menor biscoito que pode satisfazer o apetite para as demais crianças com menor apetite , e repita esta estratégia até que não haja biscoitos. o código

class Solution {
    
    
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
    
    
        sort(g.begin(),g.end());//给孩子的胃口排序
        sort(s.begin(),s.end());//给饼干的大小排序
        int child = 0,cookies = 0;
        //循环直到没有饼干和孩子
        for(child;child<g.size()&&cookies<s.size();cookies++){
    
     
            if(g[child]<=s[cookies])
                child++;//满足了的孩子数
        }
        
        return child;
    }
};

135. Distribuindo doces【Doces (Duros)】

Título Descrição
A professora quer distribuir balas para as crianças. Há N crianças em pé em uma linha reta. A professora dará a cada criança uma pontuação de acordo com seu desempenho.
Você precisa ajudar o professor a distribuir doces para essas crianças de acordo com os seguintes requisitos:
cada criança recebe pelo menos 1 doce.
A criança com a pontuação mais alta deve pegar mais doces do que os vizinhos de cada lado dela.
Então, quantos doces o professor precisa preparar pelo menos?
Amostras de entrada e saída

  • Exemplo 1
    Entrada: [1,2,2]
    Saída: 4
    Explicação:
    Você pode distribuir 1, 2 e 1 doce para essas três crianças, respectivamente.
    A terceira criança ganha apenas 1 doce, o que satisfaz as duas condições acima.

Análise
Adote a estratégia gulosa, entenda de acordo com o significado da questão, pois o número mínimo de balas é 1, inicialize primeiro a quantidade de balas para todas as crianças ser 1, após duas travessias , percorra da esquerda para a direita, quando a pontuação da criança da direita é maior que a da esquerda, a criança da direita Contagem de doces + 1; percorrer da direita para a esquerda , quando a pontuação da criança da esquerda for maior que a da direita, e o número de doces da criança criança da esquerda não é maior que a da direita, o número de doces da criança da esquerda é o número de doces da criança da direita + 1.
o código

class Solution {
    
    
public:
    
  int candy(vector<int>& ratings) {
    
    
        int size = ratings.size();
        //初始化所有孩子的糖果数为 1
        vector<int> candy_num(size,1);
        //只有一个孩子的情况
        if(size < 2)
            return size;
        //从左到右遍历
        for(int i = 1; i < size; ++i){
    
    
            //如果右边孩子分数大于左边,则多给一个糖果
            if(ratings[i] > ratings[i-1])
                candy_num[i] = candy_num[i-1] + 1;
        }
        //从右到左遍历
        for(int i = size - 1; i > 0; --i){
    
    
            //如果左边孩子分数大于右边,并且左边孩子糖果数不大于右边,则左边孩子糖果数等于右边孩子糖果数+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::accumulate,用于求和,方便一点
    }
};

problema de intervalo

435. Intervalos sem sobreposição 【Intervalos sem sobreposição (médio)】

Descrição do problemaDado
um conjunto de intervalos, encontre o número mínimo de intervalos que precisam ser removidos de modo que os intervalos restantes não se sobreponham. Nota: Pode-se considerar que o final de um intervalo é sempre maior que o seu início. Os limites dos intervalos [1,2] e [2,3] "tocam" uns aos outros, mas não se sobrepõem.
Insira n intervalos e imprima o número de intervalos que precisam ser removidos.
Amostras de entrada e saída

  • Exemplo 1
    Entrada: [ [1,2], [2,3], [3,4], [1,3] ]
    Saída: 1
    Explicação:
    Depois de remover [1,3], os intervalos restantes não se sobrepõem.

Análise
Usando uma estratégia gulosa, de acordo com o significado da questão, podemos ordenar as caudas de cada intervalo, e dar prioridade aos intervalos com as menores terminações que não se sobreponham aos intervalos anteriores. Conforme exemplo 1, após a ordenação, deve ser: [[1,2], [2,3], [1,3], [3,4]]. A estratégia gananciosa é: primeiro reter o intervalo com a menor cauda e não se sobrepõe, [1,2] e [1,3] se sobrepõem, então removemos [1,3].
o código

class Solution {
    
    
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
    
    
        //判断区间是否为空
        if(intervals.empty())
        {
    
    
            return 0;
        }
        //给每个区间尾排序,sort(a,b,c) 条件c返回的是个bool值。
        sort(intervals.begin(),intervals.end(),[](vector<int>& a,vector<int>& b)
        {
    
    
            return a[1]<b[1];//使用两个vector数组存放区间尾,进行排序。
        });
        int n = intervals.size();
        int t = 0, pre = intervals[0][1];//选中第一个区间的区间尾
        for(int i = 1;i < n;i++)
        {
    
    
            if(intervals[i][0] < pre){
    
     //如果区间头部<该选中区间的尾部,则区间重叠
                t++;
            }
            else{
    
    
                pre = intervals[i][1];
            }
        }
        return t; 
    }
};

Incompleto.

おすすめ

転載: blog.csdn.net/qq_43759081/article/details/121629080