假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 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;
}