狭义的贪心算法指的是解最优化问题的一种特殊方法,解决过程中总是做出当下最好的选择,因为具有最优子结构的特点,局部最优解可以得到全局最优解;这种贪心算法是动态规划的一种特例。能用贪心解决的问题,也可以用动态规划解决。
广义的贪心指的是一种通用的贪心策略,基于当前局面而进行贪心决策。举个例子:
12.整数转罗马数字
罗马数字包含以下七种字符:
I,V,X,L,C,D和M,分别表示1,5,10,50,100,500,1000。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
Simple Test Cases
1 | 输入: 3 |
本题从贪心算法的思路入手,可以考虑将目标数值,不断减去所能减去的最大的进位,得到罗马数字的表示:
1 | class Solution { |
再来看另一道题,有时候题干并不会太明显地令你使用贪心算法,一定要灵活思考。
452. 用最少数量的箭引爆气球
在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以y坐标并不重要,因此只要知道开始和结束的x坐标就足够了。开始坐标总是小于结束坐标。平面内最多存在10000个气球。
一支弓箭可以沿着
x轴从不同点完全垂直地射出。在坐标x处射出一支箭,若有一个气球的直径的开始和结束坐标为$x{start}$,$x{end}$, 且满足$x{start} ≤ x ≤ x{end}$,则该气球会被引爆。可以射出的弓箭的数量没有限制。弓箭一旦被射出之后,可以无限地前进。我们想找到使得所有气球全部被引爆,所需的弓箭的最小数量。
Simple Test Cases
1 | 输入: |
一种可行的思路是,对气球数组按末端大小进行排序,当两个气球不相交时,必然需要两支弓箭,反之,一支就行了,故而这亦是贪心算法的运用。
1 | class Solution { |
此外,要注意对数组进行排序时,在C++排序函数尽量使用>、<、=符号,不要使用+、-符号,后者可能会出错。