春招Leetcode刷题日记-D1-贪心算法-分配问题


何为贪心

1、顾名思义,贪心算法采用贪心的策略,保证每次操作都是局部最优的,从而使最
后得到的结果是全局最优的。
2、贪心算法使用原则

1、最优子结构:规模较大的问题的解由规模较小的子问题的解组成,规模较大的问题的解只由其中一个规模较小的子问题的解决定;
2、无后效性:后面阶段的求解不会修改前面阶段已经计算好的结果;
3、贪心选择性质:从局部最优解可以得到全局最优解。

力扣455. 分发饼干

题目链接:455. 分发饼干
在这里插入图片描述
在这里插入图片描述

思路

1、明确本题目标:用手里的饼干,满足尽可能多的孩子
2、根据上面的目标,我们必须利用好手里的饼干,不能出现,孩子的胃口是1,有2/3/4大小的饼干,我们就要避免"浪费",所以就要给孩子最接近他胃口的饼干
3、这样,每个人都可以获得最接近他胃口的饼干,都不会造成"浪费",才能让更多的人得到饼干,这就是本题的贪心策略。

注意:
1、这种题,明显存在数组,并且我们解题需要使用到数组之中数字关系
2、但是,数组之中,是乱序,一定记住这个大原则:乱序会让时间复杂度最糟糕!
3、所以,第一步就是对两个数组进行排序
4、这样,从胃口最小的孩子入手,当前饼干连这个孩子都满足不了,则说明一定是无用饼干,就看下一个饼干去;若能满足,则一定是最优的。

代码

class Solution {
public:
	int findContentChildren(vector<int>& g, vector<int>& s) {
		sort(s.begin(), s.end());//排序
		sort(g.begin(), g.end());
		int i = 0, j = 0;//分别指向数组g s
		int g_size = g.size(), s_size = s.size();
		int ans = 0;//答案
		while (i < g_size&&j < s_size) {
			if (s[j] < g[i]) {//当前饼干连胃口最小的孩子都满足不了,一定不能满足任何一个孩子
				j++;
				continue;
			}
			else {//当前饼干一定是最适合当前胃口的孩子,并且之后的饼干一定大于了当前饼干造成了浪费,所以选后面的饼干会造成满足孩子的数量减少
				ans++;
				i++;
				j++;
			}
		}
		return ans;
	}
};

力扣135. 分发糖果

题目链接:135. 分发糖果
在这里插入图片描述
在这里插入图片描述

思路

1、贪心策略

1、根据题意,最开始,为每一个人分配一个糖果
2、比如相邻的两个孩子 A B,无非就是两种情况:左面的人等级高;右面的人等级高。
3、但是在一个等级序列中,我们无法确认,相邻的一对人,属于上面那种情况之一,所以贪心策略就来了:先从左到右,一对一对相邻的看,只要右面的等级高,糖果就多;然后再从右到左,只要左面的等级高,糖果就多。
4、这样扫两遍,就满足题意了

2、因为第一遍扫的时候,大家刚初始化玩,糖果数都是1,所以右面的等级高的话,应得到左面糖果数+1
3、第二遍扫的时候,左面等级高的话,可能本身糖果数就是多的,也可能不多,所以要二者之间取max,保证符合题意

代码

class Solution {
public:
	int candy(vector<int>& ratings) {
		int ans = 0;
		int n = ratings.size();
		vector<int> cnt(n, 1);
		for (int i = 0; i < n - 1; i++) {//从左到右
			if (ratings[i] < ratings[i + 1]) {
				cnt[i + 1] = cnt[i] + 1;
			}
		}
		for (int i = n - 1; i > 0; i--) {//从右到左
			if (ratings[i - 1] > ratings[i]) {
				cnt[i - 1] = max(cnt[i - 1], cnt[i] + 1);
			}
		}
		for (int i = 0; i < n; i++) {
			ans += cnt[i];
		}
		return ans;
	}
};

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JLU_LYM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值