什么是贪心算法?
贪心算法是一种在求解问题时,逐步构建解决方案的算法范式。它在每一步中选择当前状态下的局部最优解,希望通过一系列局部最优解最终得到全局最优解。贪心算法适用于具有贪心选择性质和最优子结构的问题:
- 贪心选择性质:可以通过选择当前的局部最优解来逐步达到全局最优解。
- 最优子结构:问题的整体最优解可以通过其子问题的最优解构成。
需要注意的是,贪心算法并不总是能保证找到全局最优解,因此适用问题必须满足上述性质。
例题:分发饼干问题
问题描述:
有一群孩子和一堆饼干,每个孩子有一个贪心指数(需要的最小饼干大小),每块饼干也有一个大小。只有当一块饼干的大小大于或等于某个孩子的贪心指数时,孩子才能获得饼干。求最多可以分配的孩子数量。
输入:
g[]
:孩子的贪心指数数组(贪心指数是正整数)。s[]
:饼干大小数组(饼干大小是正整数)。
输出:
- 最多可以满足的孩子数量。
解法:贪心算法
思路:
- 将孩子的贪心指数和饼干大小分别排序。
- 使用两个指针,分别指向孩子数组和饼干数组。
- 遍历饼干数组,如果当前饼干大小满足某个孩子的需求,则分配给该孩子,并移动两个指针;否则只移动饼干指针。
- 直到饼干分配完或者所有孩子都满足。
import java.util.Arrays;
public class GreedyAlgorithmExample {
public static int findContentChildren(int[] g, int[] s) {
// 排序孩子的需求和饼干的大小
Arrays.sort(g);
Arrays.sort(s);
int child = 0, cookie = 0;
while (child < g.length && cookie < s.length) {
// 如果饼干能满足当前孩子
if (s[cookie] >= g[child]) {
child++; // 满足一个孩子
}
cookie++; // 尝试下一个饼干
}
return child; // 返回被满足的孩子数量
}
public static void main(String[] args) {
int[] g = {1, 2, 3}; // 孩子的贪心指数
int[] s = {1, 1}; // 饼干大小
System.out.println("最多可以满足的孩子数量: " + findContentChildren(g, s));
}
}
测试用例
输入:
- 孩子的贪心指数:
g = [1, 2, 3]
- 饼干大小:
s = [1, 1]
输出:
最多可以满足的孩子数量:1
解释:
- 第一个饼干(大小为 1)满足第一个孩子(贪心指数为 1)。
- 第二个饼干无法满足剩余的孩子。
输入:
- 孩子的贪心指数:
g = [1, 2]
- 饼干大小:
s = [1, 2, 3]
输出:
最多可以满足的孩子数量:2
解释:
- 第一个饼干(大小为 1)满足第一个孩子(贪心指数为 1)。
- 第二个饼干(大小为 2)满足第二个孩子(贪心指数为 2)。
贪心算法的优点:
- 简单高效,只需一次排序和线性遍历,时间复杂度为 O(nlogn)O(n \log n)O(nlogn)。
- 使用贪心选择避免了不必要的复杂性,适合处理资源分配问题。