昨晚,知了堂校招冲刺的小伙伴在社群里分享了“贪心算法”,知了姐收获颇多,今天整理出来给大家也分享一下。
前言
贪心是人类自带的能力,贪心算法是在贪心决策上进行统筹规划的统称。
基本概念:
贪心算法(又称贪婪算法)在百度百科中是这样解释的:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。
小案例:
题目描述:(分发饼干)
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
注意:
你可以假设胃口值为正。
一个小朋友最多只能拥有一块饼干。
示例 1:
输入: [1,2,3], [1,1]
输出: 1
解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。
示例 2:
输入: [1,2], [1,2,3]
输出: 2
解释:
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.
那么让我们来分析一波:
饼干大小是不相同的,每个孩子的胃口也是有大有小。我们最先想到的应该就是用尽量小的饼干去尽量满足胃口大的孩子,这里就是这个问题的局部最优解了,那么这里采用贪心策略就再合适不过了。话不多说,上代码!
class Test {
//贪心的思想是,用尽量小的饼干去满足小需求的孩子,所以需要进行排序先
public int findContentChildren(int[] g, int[] s) {
int child = 0;
int cookie = 0;
Arrays.sort(g); //先将饼干 和 孩子所需大小都进行排序
Arrays.sort(s);
while (child < g.length && cookie < s.length ){ //当其中一个遍历完毕就结束
if (g[child] <= s[cookie]){ //当用当前饼干可以满足当前孩子的需求,可以满足的孩子数量+1
child++;
}
cookie++; // 饼干只可以用一次,因为饼干如果小的话,就是无法满足任何孩子就被抛弃,满足的话就是被用了
}
return child;
}
}
采用这种方式就能完美的解决这个问题
既然案例看完了,让我们来总结一下:
贪心算法,简单的说就是在不产生后效性的条件下,总是采用最优的解法,是一个个局部最优解合成的最优的一种高效的算法。
欢迎大家一起来交流~~