1. 题目描述
题目中转:455.分发饼干
2.详细题解
饼干有限且每块饼干有一个尺寸,不同孩子对饼干的胃口值不一样,如何分配饼干,才能使得满足了胃口的孩子最多。
假设饼干数量为cookie,孩子数量为children,如果采用枚举的方式,当
c
o
o
k
i
e
>
c
h
i
l
d
r
e
n
,
cookie>children,
cookie>children,时,则一共有
A
c
o
o
k
i
e
c
h
i
l
d
r
e
n
=
c
o
o
k
i
e
!
(
c
o
o
k
i
e
−
c
h
i
l
d
r
e
n
)
!
\begin{array}{c} A_{cookie}^{children}=\frac{cookie!}{\left( cookie-children \left) !\right. \right.} \end{array}
Acookiechildren=(cookie−children)!cookie!种可能,即排列组合问题,对于第1个孩子有cookie种分配可能,第2个孩子则有
(
c
o
o
k
i
e
−
1
)
(cookie-1)
(cookie−1)种可能,依次类推,每个孩子的可能数量相乘即为总可能数,即排列组合公式;当
c
o
o
k
i
e
<
=
c
h
i
l
d
r
e
n
,
cookie<=children,
cookie<=children,的时候,则一共有
A
c
h
i
l
d
r
e
n
c
o
o
k
i
e
=
c
h
i
l
d
r
e
n
!
(
c
h
i
l
d
r
e
n
−
c
o
o
k
i
e
)
!
\begin{array}{c} A_{children}^{cookie}=\frac{children!}{\left( children-cookie \left) !\right. \right.} \end{array}
Achildrencookie=(children−cookie)!children!种可能,相当于只有cookie个孩子能分配到饼干,这个时候为便于理解可以换个思路,第1块饼干分配有children个孩子可能,第2块饼干分配有
(
c
h
i
l
d
r
e
n
−
1
)
(children-1)
(children−1)个孩子可能,所有可能结果同乘则为总可能数;对于上述两种情况,则需要从所有可能中找出满足胃口孩子最多的情况。
对于上述无论那种情况,算法的时间复杂度为 O ( n ! ) O(n!) O(n!),即使m和n的最小值为100,则需要遍历 100 ! 100! 100!种可能才能找到问题的答案,显示是不可取的。
要求让尽量的多的孩子满足,那么什么孩子最容易满足呢?当然是胃口越小的越容易满足(PS:因为胃口越小,能够满足的饼干尺寸越多,选择满足的最小尺寸,剩下的饼干又可以满足更大胃口的孩子,进而能够满足的孩子数量越多)。
因此首先从最小胃口的孩子开始考虑,为满足更多其余孩子的情况,因此仅选择满足当前孩子胃口的最小饼干分配给他(如果不是满足当前孩子最小的,选了一个大的,那这个最小的也不会满足其它孩子的胃口;而选择了当前满足最小的,余留大的可能会满足其他孩子,因此数量会更多)。满足了当前孩子后,对于剩余的孩子依次采用相同的策略,考虑剩余孩子中最小胃口的孩子,直到所有孩子均查看完或者没有饼干再分即结束。
既然要从最小孩子开始判断,因此孩子的胃口需要先排序,同理,是从最小尺寸的饼干开始判断,饼干的尺寸也需要先排序;孩子胃口和饼干的尺寸均是用数组(python里面叫列表)进行存储的,为了表示当前判断了那个孩子和那块饼干,可以分别用一个指针进行记录,即双指针方法。
3.代码实现
3.1 Python
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
g.sort() # 孩子胃口排序
s.sort() # 饼干尺寸排序
g_index, s_index = 0, 0 # 初始为第一个孩子和第一块饼干
m, n = len(g), len(s)
ans = 0 # 初始化满足的孩子数量
while g_index < m and s_index < n: # 继续判断的条件是还有孩子且还剩有饼干
if g[g_index] <= s[s_index]: # 当前孩子胃口满足
g_index += 1 # 孩子指针+1
ans += 1 # 数量 + 1
s_index += 1 # 无论是否满足,饼干指针均+1
return ans
3.2 Java
class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int m = g.length;
int n = s.length;
int g_index =0, s_index = 0;
int ans = 0;
while (g_index < m && s_index < n){
if (g[g_index] <= s[s_index]){
g_index++;
ans++;
}
s_index++;
}
return ans;
}
}
执行用时不必过于纠结,对比可以发现,对于python和java完全相同的编写,java的时间一般是优于python的;至于编写的代码的执行用时击败多少对手,执行用时和网络环境、当前提交代码人数等均有关系,可以尝试完全相同的代码多次执行用时也不是完全相同,只要确保自己代码的算法时间复杂度满足相应要求即可,也可以通过点击分布图查看其它coder的code