基本概念:

所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择,贪心策略使用的前提是局部最优能导致全局最优。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。

贪心算法的基本思路:

1.建立数学模型来描述问题。

2.把求解的问题分成若干个子问题。

3.对每一子问题求解,得到子问题的局部最优解。

4.把子问题的解局部最优解合成原来解问题的一个解。

实现框架:

从问题的某一初始解出发;

while (能朝给定总目标前进一步){

利用可行的决策,求出可行解的一个解元素;

}

由所有解元素组合成问题的一个可行解;

下面给出Leetcode示例:

45. Jump Game II

这道题的要求是给定一整数数组,数组元素表示每次可以跳跃的最大距离。然后初始位置在数组的第一个元素,目的是以最少的步数到达最后元素。

例如A={2,3,1,1,4},初始位置0出为2,最终跳的最少次数是2,即先从0跳到1位置,此时1位置是3,正好可以一次跳到结束位置,加起来正好两次是最小次数了。

采用贪心算法,引入reach变量表示可以能到达的最远处,这也就是全局最优解;当遍历到i时,局部最优解即次局部下最远可达位置A[i]+i,此时全局的最优解reach和A[i]+i的最大值,即reach=max(reach,A[i]+i)

除此之外还要记录跳的次数,至于什么时候step需要加1?答案是当前的i超过了前一步的最远位置。所以引入last变量记录上一步能到达的最远位置。

代码:

int jump(vector<int>& nums){
int reach=0;//全局最远可达位置
int last=0;//上一步最远能到达位置
int step=0;//i需要超过上一步最远位置时加1for(int i=0;i<=reach&&i<nums.size();i++){if(i>last){step++;last=reach;}reach=max(reach,nums[i]+i);}
return reach>=(nums.size()-1)?step:0;//超过也算是到了终点}

121. Best Time to Buy and Sell Stock

一个序列代表每天股票卖出价格,贪心法,分别找到价格最低和最高的一天,低进高出,注意最低的一天要在最高的一天之前且只能交易一次。遍历一次,由局部推出全局最优。

int maxProfit(vector<int>& prices){
int res=0;
if(prices.size()<=1)return res;
int curmin=prices[0];for(int i=0;i<prices.size();i++){if(curmin>prices[i])curmin=prices[i];if(res<(prices[i]-curmin))res=(prices[i]-curmin);}//只要大于前者就是收益return res;
}

122. Best Time to Buy and Sell Stock II

相比121,本题有多次买卖机会,同一时刻只能持有一个股票,只有当当前的股票卖掉才能买新的股票。例如:2 3 1 5 6 9 2 那么最大的利益就是2-3和1-9段相加为9。故只需找出局部递增序列。

    int maxProfit(vector<int>& prices) {
int res=0;
if(prices.size()<=1)return res;
for(int i=0;i<prices.size();){int j=i;while(j+1<prices.size()&&prices[j+1]>prices[j])j++;if(j==i){i++;}//一开始就不增加else {res+=prices[j]-prices[i];i=j+1;}//增加若干}
return res;
}

123. Best Time to Buy and Sell Stock III
该题最多两次交易。类似121,只不过考虑到最多两次交易,可从前后两段开始。

    int maxProfit(vector<int>& prices) {
int res=0;
if(prices.size()<=1)return res;
//分前后两段
vector<int> pre(prices.size(),0);
vector<int> aft(prices.size(),0);
//pre iterator
int curmin=prices[0];
for(int i=1;i<prices.size();i++){if(curmin>prices[i])curmin=prices[i];pre[i]=max(prices[i]-curmin,pre[i-1]);}
//after
int curmax=prices[prices.size()-1];
for(int i=prices.size()-2;i>=0;i--){if(curmax<prices[i])curmax=prices[i];aft[i]=min(prices[i]-curmax,aft[i+1]);//负数}
//merge
for(int i=0;i<prices.size();i++)if(res<pre[i]-aft[i])res=pre[i]-aft[i];//负数,所以减去aft
return res;
}

五大经典算法之四贪心算法相关推荐

  1. 五大算法之三--贪心算法

    一.基本概念:        所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解.      贪心算法没有固定的 ...

  2. python贪心算法最短路径_dijkstra算法(贪心算法)——解决最短路径问题

    最短路径 给定一张带权图和其中的一个点(作为源点),求源点到其余顶点的最短路径 基本思想 1)源点u,所有顶点的集合V,集合S(S中存有的顶点,他们到源点的最短路径已经确定,源点u默认在S中),集合V ...

  3. 数据结构与算法之美(十四)算法思想——贪心算法

    目录 贪心算法介绍 贪心算法例子 1. 背包 2. 分糖果 3. 钱币找零 4. 区间覆盖 5. 区间覆盖的延伸:任务调度.教师排课 贪心算法经典应用 1. 霍夫曼编码 2. 最小生成树算法 3. 最 ...

  4. 3.Python算法之贪心算法思想

    贪心算法 1.什么是贪心算法 2.贪心算法的特点和思路 3.贪心算法的缺点 4.贪心算法的基本思路 5.贪心算法的基本过程 6.贪心算法解决"找零"问题 6.贪心算法解决" ...

  5. 回溯算法和贪心算法_回溯算法介绍

    回溯算法和贪心算法 回溯算法 (Backtracking Algorithms) Backtracking is a general algorithm for finding all (or som ...

  6. java调度问题的贪心算法_贪心算法——换酒问题

    知识回顾 贪心算法 (greedy algorithm),又称贪婪算法. 是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法. 贪心算法在 有最优子 ...

  7. 任务分配算法c语言程序,程序员算法基础——贪心算法

    原标题:程序员算法基础--贪心算法 前言 贪心是人类自带的能力,贪心算法是在贪心决策上进行统筹规划的统称. 比如一道常见的算法笔试题跳一跳: 有n个盒子排成一行,每个盒子上面有一个数字a[i],表示最 ...

  8. 贪心算法适用条件_【算法】贪心算法

    概念&&介绍 贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解.所以说只有证明局部最优解在全局最优解 ...

  9. 趣学算法系列-贪心算法

    趣学算法系列-贪心算法 声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门, 原作者博客链接,本书暂无免费电子版资源,请大家支持正版,更多的案例分析请查看原书内容. 第二章 ...

最新文章

  1. 如何写一篇好的技术博客
  2. python 实现结构树模式显示目录下文件
  3. 强大的shell常用命令集锦
  4. 透过水晶球一瞥下一代SOC
  5. [云炬创业基础笔记]第二章创业者测试16
  6. __typeof__() 、 __typeof() 、 typeof()的区别
  7. 谷歌又放大招:视觉效果完胜其他SOTA的风格迁移网络,手机端可达实时4K
  8. iOS底层面试题--RunLoop
  9. [pytorch、学习] - 3.9 多重感知机的从零开始实现
  10. matlab win10 gpu加速,win10的Edge浏览器设置GPU硬件加速,大幅度提升浏览器性能
  11. 往事历历在目--我的2009年工作总结
  12. Linux下Centos7以rpm方式离线安装MySQL5.7教程以及部分报错解决方案
  13. LaunchImage命名与AppIcon命名(ios设置 启动图片和AppIcon图片)
  14. 【Shell】压缩相关命令
  15. Windows中ElasticSearch的备份和还原
  16. Casewhen和Decode
  17. 资产证券化为什么需要区块链技术?专访趣链科技揭开“区块链+ABS”迷雾
  18. Linux学习16 软件包和启动项管理
  19. 中国运营商考虑用WiFi亭代替公共电话亭
  20. (4)[Tensorflow]L2正则化和collection【tf.GraphKeys】

热门文章

  1. Java的图书商城项目如何添加商品到购物车
  2. 逻辑回归(Logistic Regression)原理(理论篇)
  3. 一种测试FPS的方法
  4. 2020北航计算机夏令营机试题目个人理解
  5. Java中Math函数的使用
  6. *Linux下的USB总线驱动 u盘驱动分析*
  7. 画出优秀手绘线稿的必备条件,首先要满足和避免这些线条
  8. 如何轻松学习C语言编程!
  9. 从聚焦沉淀到探索创新,跨境支付正在酝酿下一个行业浪潮
  10. [BZOJ3441] 乌鸦喝水