贪心算法

简介

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。
贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间
贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。
虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯。(即某个状态以后的过程不会影响以前的状态,只与当前状态有关)

基本思想

  • 求解最优化问题的算法包含一系列步骤
  • 每一步都有一组选择
  • 作出在当前看来最好的选择
  • 希望通过作出局部最后选择达到全局最后选择
  • 贪心算法是否能产生最优解,需要严格证明

产生最优解的条件

  • 最优子结构
    一个问题的最优解包含子问题的最优解时,称这个问题具有最优子结构。
  • 贪心选择性
    当一个问题的全局最优解可以通过局部最优解得到的时候,称这个问题具有贪心选择性。

存在的问题

贪心算法也存在如下问题:
1、不能保证解是最佳的。因为贪心算法总是从局部出发,并没从整体考虑 ;
2、贪心算法一般用来解决求最大或最小解
3、贪心算法只能确定某些问题的可行性范围

适用情况举例

贪心策略适用的前提是:局部最优策略能导致产生全局最优解。
许多典型的算法实际上就是贪心算法:

  • 哈夫曼树
    带权路径长度最小的二叉树就是哈夫曼树。在哈夫曼树中,权值越大的节点离根越近。

  • 最小生成树(Kruskal算法/Prim算法)
    Kruskal算法:判断权值最小的边的两端是否属于不同连通分量
    Prim算法:从所有一端已加入树中,一端未加入树中的节点中选择权值最小的边

  • 最短路径(Dijkstra算法)
    1、设v0为原点,S={v0},dist[v0]=0;
    2、找到u∈S,v∉S,使得dist[u]+edge[u][v]最小,则将v加入S中,并且v0到v的最短路径为dist[v]=dist[u]+edge[u][v]
    3、重复上述过程,直至所有顶点都加入S中

贴一道印象深刻的题:

  • 在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。开始坐标总是小于结束坐标。
    一支弓箭可以沿着 x 轴从不同点完全垂直地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被引爆。可以射出的弓箭的数量没有限制。 弓箭一旦被射出之后,可以无限地前进。我们想找到使得所有气球全部被引爆,所需的弓箭的最小数量。
    给你一个数组 points ,其中 points [i] = [xstart,xend] ,返回引爆所有气球所必须射出的最小弓箭数。
    链接:leetcode 452. 用最少数量的箭引爆气球

    思路: 将points中的元素按照xstart值由大到小排序,从xstart最大值开始依次作为x值,引爆气球,直至所有气球都被引爆。

心得

2020年秋招过程中,感觉有一些算法是经常被问到的,在看大厂面经时,经常涉及修改算法减少时间复杂度的情况。
前边那道射爆气球的问题是在LeetCode上刷到的,可能还会有其他更好的方法,放在这里作为例子,只是做一个思路上的总结。在遇到求最大/最小解时,可以考虑贪心算法。
算法的学习对我来说可能是比较痛苦的,最近开始尝试写博客,记录自己的学习进度和心得,希望自己能坚持学习,找到自己的学习方式和高效的学习方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值