leetcode-455-分发饼干

博客围绕孩子分饼干问题展开,每个孩子有胃口值,每块饼干有尺寸,目标是满足最多孩子。介绍了多种解决方法,如先对胃口最小的小孩分配最小尺寸饼干、给最大胃口的小孩分配最大尺寸饼干等,还提及了各方法在时间效率上的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

示例 1:

输入: g = [1,2,3], s = [1,1]
输出: 1
解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。

示例 2:

输入: g = [1,2], s = [1,2,3]
输出: 2
解释:
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.

根据题意,所能想到的解决方法就是先对胃口最小的小孩分配最小尺寸的饼干,最开始是用双重循环做的,毫无疑问超出了时间。因为我们在一些不可能发生的事情上浪费了时间,假如对于一个胃口比较小的小孩,都已经没有饼干能满足他/她的胃口了,那胃口更大的小孩还需要判断吗?

后来想到了一个给最大胃口的小孩分配最大尺寸的饼干的方法,虽然最开始的饼干分配十分迅速,但是很可惜还是没有满足时间要求。对于从大到小的分配,很难通过剪枝来减少时间,因为胃口大的吃不饱不代表胃口小的吃不饱。

/*
未通过:超出时间限制
*/
int findContentChildren(vector<int>& g, vector<int>& s) {
	sort(g.begin(), g.end());
	sort(s.begin(), s.end());
	vector<bool> beEaten(s.size(),false);
	int n = 0;//吃到饼干的小孩个数
	int gi = 0;
	int j;
	for (int i = g.size() - 1; i >= 0; --i) {
		gi = g[i];
		for (j = s.size() - 1;j >= 0; --j) {
			if (beEaten[j] == false) {
				if (gi <= s[j]) {
					beEaten[j] = true;
					++n;
				}
				break;
			}
		}
	}
	return n;
}

还是需要从小到大来判断。

/*
执行结果:通过
执行用时:88 ms, 在所有 C++ 提交中击败了61.08%的用户
内存消耗:17.4 MB, 在所有 C++ 提交中击败了41.83%的用户
*/
int findContentChildren(vector<int>& g, vector<int>& s) {
	sort(g.begin(), g.end());
	sort(s.begin(), s.end());
	int n = 0;//吃到饼干的人数
	int gi;
	int sIndex = 0;//饼干序号,当前分配饼干的编号
	for (auto i = 0; i < g.size() && sIndex<s.size();++sIndex) {
		gi = g[i];
		if (gi <= s[sIndex]) {
			n++;//分配饼干
			i++;//下一个小孩
		}
	}
	return n;
}

终于通过了,但速度还是不够快。由于我们是让一个孩子吃饱后再解决下一个孩子,因此i的值其实就是n的值,这里n++浪费了一点点时间。

/*
执行结果:通过
执行用时:84 ms, 在所有 C++ 提交中击败了80.14%的用户
内存消耗:17.4 MB, 在所有 C++ 提交中击败了37.54%的用户
*/
int findContentChildren(vector<int>& g, vector<int>& s) {
	sort(g.begin(), g.end());
	sort(s.begin(), s.end());
	int gIndex = 0;
	for (int sIndex = 0; sIndex < s.size();++sIndex) {
		if (gIndex >= g.size())
			break;
		if (g[gIndex] <= s[sIndex]) 
			gIndex++;
	}
	return gIndex;
}

这种方法可以用一种相对优雅点的方式写出:

int findContentChildren(vector<int>& g, vector<int>& s) {
	sort(g.begin(), g.end());
	sort(s.begin(), s.end());
	int n = 0,sIndex = 0;
	while (n < g.size() && sIndex < s.size()) {
		if (g[n] <= s[sIndex]) ++n;
		++sIndex;
	}
	return n;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值