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 .
Exercícios de Leetcode
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.