贪心算法
概述
贪心的本质是选择每一阶段的局部最优,从而达到全局最优。难点在于如何通过局部最优推出全局最优。如果感觉能用贪心的话可以手动模拟试一试。我觉得贪心的套路就是当前要保持一个什么最值,然后遇到什么情况要更新这个最值。
简单题目
455.分发饼干:这道题算是一道贪心中很简单的题,我觉得比较容易想到的方式是让小饼干喂饱胃口小的。
1005.K次取反后的最大数组和:这道题当然不难,但是如果考虑不周全也容易出错,而且有两个地方可以用贪心的思想去想。
860.柠檬水找零:这道题只需要把所有情况都分出了,并且在最后一种情况用一个小贪心即可。
中等题目
序列问题
376.摆动序列:这个题不看题解感觉有点做不出来,主要是把我们要求的序列看作山峰,我们要做的就是求峰顶加峰谷的数量,要删除的就那些单调增减的部分。主要讨论一下只有一个或两个的情况。
738.单调递增的数字:这个题其实看懂了示例就能有思路,从前往后遍历可以,不过当前的改变可能影响之前的改变,很多题都有这种情况,这道题从后往前遍历会好一点,因为从后往前遍历当前的改变不会影响之前的。不过从后往前需要记录在哪里开始变9.
股票问题
122.买卖股票的最佳时机II:这道题就是让当前手中持有的股票价值最低,然后只要遇到比当前价值高的就卖出获得利润,如遇到更低的则更换股票。
714.买卖股票的最佳时机还手续费:这道题在买入时期没什么好说的,哪天的手续费加price最低就买哪一天,关键是卖出的时候,之前我们卖出是只要有正利润就可以卖出,因为之前利润是可以传导,而这里利润的传导要减去手续费就会有损失,所以当要传导的时候我们的初始加个就不要加上手续费了,这样让传导没有损失。
两个维度衡量问题
135.分发糖果:这道题要从左至右和从右至左分别考虑一次,且从右至左考虑的时候还要考虑上一次考虑的结果。
406.根据身高重建队列:这道题和上面那道题区别还是挺大的,也是两个维度,不过是从两个属性的维度,先按照身高从大到小排序,再按h插入即可,因为按照身高排序后再按h插入肯定不可能往后插(题目保证有解),那只要往前插,因为前面的都是高于它的,所以它不影响前面的人,那么只要按照h插就能得到满足条件的结果。另外,vector的扩容很耗时的,因为又要开辟空间,又要复制,又要释放原来的空间。
有点难度
区间问题
55.跳跃游戏:这道题我们要保持的当前的最值就是最大的右边界,然后左边界依次遍历,如果能够得到更大的右边界就更新,只要右边界超过后等于最后一个位置则说明可以跳到。
45.跳跃游戏II:在上面那道题中只需要保持一个当前能到达的最大值即可,但在这道题还有保持在当前范围内下一步能到达的最大值,即要保持的最值成了下一步的最大范围。
452.用最少数量的箭引爆气球:一开始肯定想到要排序,但是排序之后算重叠区间发现情况也很多,其实这个题只要保持最小右边界然后判断当前气球与最小右边界的关系即可,因为反正只要当前左边界大于最小右边界就要多射一支箭,就直接不用再考虑之前的了。
435.无重叠区间:这道题和452简直是对称的,452是按左边界排序,左边界越小越越靠左,然后如果当前左边界小于最小右边界可以重复,大于则要增加成本;而这道题是按右边界排序,右边界越小越靠左,右边界越小给别人留出的空间就越大,如果当前左边界小于最小右边界则需要移除。
763.划分字母区间:这道题和452以及435比较像,不过那两道题是保持最小右边界并比较,而这道题是在遍历的过程中求最大右边界,如果到最大右边界则说明可以分割为一段。
56.合并区间:这道题也是先按左边界排序,然后按照最大右边界的原则来合并区间。
其他问题
53.最大子数组和:这道题的思路就是如果当前和为负数,则它对后面的贡献为负,所以直接不要当前和重新算起,如果为正数则要继续算,中间记录最大连续和。
134.加油站:这道题其实和53有一点像,将余量加起来,如果当前余量小于0说明之前区间的都不行(因为之前的都是大于等于0,现在小于0说明从之前任何一个点出发都填不了这个坑),于是当前余量归0,从后一个开始继续算,最后如果总余量小于0则不行,否则直接返回即可,因为只要能成功,说明我们找到的位置就是可以的。
968.监控二叉树:这道题的贪心点就在于要从叶节点的父节点开始按摄像头,然后每隔两个安一个。所以从下往上遍历,用后序遍历,且要用三个数字来表示节点状态以让父节点判断状态,且空节点的状态应该是有覆盖,且还要判断头结点是否有覆盖。