贪心算法学习笔记

贪心算法

简要理解

贪心算法是分阶段工作的,在每一个阶段,他都会选择工作它认为眼下所作决定最好的,它是不考虑将来结果的,他只在乎局部最优解,算法终止时,我们希望得到的局部最优的结构就是全局最优,如果是就说明算法是正确的,否则算法得到的是一个次最优解,如果不要求绝对最佳答案,有时可以用简单的贪心算法生成近似答案,它的好处是在处理较大数据,较复杂的问题时,一般时间复杂度与空间复杂度都比产生准确答案的复杂算法要快上很多倍得到一个几乎接近正确的答案。

经典示例

  • 找零钱问题:为了使用货币找零钱,求找出零钱张数最少值,我们可以重复配发最大额货币,于是为了找一百七十五元,我们肯定先选一张一百的,再拿一张五十的,再拿一张二十,五块的,这里就用到了贪心算法每一步选取局部最优解的思想,而且在这个问题中,局部最优就是整体最优.
  • 求最快抵达路径:在北京的某个交通高峰期间,有些主要干道可能看起来是空空荡荡的,但你最好还是不要选择这条干道,因为交通可能会在你抵达是=时突然变得车水马龙。这就是贪心算法行不通的例子

经典应用

  1. 作业调度问题 对于多个作业(假设每个作业需要批改时间不同),我们有多个老师参与批阅,假设每个老师批阅速度一致,我们该如何想办法让整体完成时间最快。 这里就可以用到贪心算法的思想,我们可以给第一个老师挑时间最短的。第二个挑第二短的,在这样依次下去,保证每个老师先拿到的作业都是目前它眼中最好批改的作业。 这样做,虽然不一定能使整体批阅时间达到最低,但是他决定使较为接近最低的答案。而且它的算法执行复杂度会比准确算法要低,如果数据很大,贪心算法的优势为变得越来越明显

  2. 哈夫曼编码

    • 哈夫曼编码是从底向顶的构造哈夫曼树,我们每次挑取两个权值最小的元素连接构成某节点的左右子树,然后把两个左右子树的权值相加,赋给连接这两颗子树的节点,再接着这么操作,就可以把一个字符串按权重大小编码且不影响读取,字符根节点往左为0,往右为1,那么出现频率最高的字符的位数一定是最小的,这样一来就可以减小空间成本
    • 哈夫曼编码使用贪心算法的地方在于,他没有对整体数据进行分析,也是每次运行优先挑取两个权值最小的树,也就是局部最优解,这里就反映出了贪心算法的本质。
    • 流程示例 alt 哈夫曼树构建流程