贪心基础css
贪心(Greedy)经常使用于解决最优问题,以期经过某种策略得到一系列局部最优解、从而求得总体最优解。html
贪心从局部最优角度考虑,只适用于具有无后效性的问题,即某个状态之前的过程不影响之后的状态、紧接下来的状态仅与当前状态有关。和分治、动态规划同样,贪心是一种思路,不是解决某类问题的具体方法。git
应用贪心的关键,是甄别问题是否具有无后效性、找到得到局部最优的策略。有的问题比较浅显,例如一道找零钱的题目 LeetCode 860. Lemonade Change:github
// 860. Lemonade Change bool lemonadeChange(vector<int>& bills) { int five=0,ten=0; for(auto i:bills){ if(i==5) five++; else if(i==10) ten++,five--; else if(ten>0) ten--,five--; else five-=3; if(five<0) return false; } return true; }
以上策略的核心就是每轮找零用最大的面额、保留尽可能多5元纸币。算法
相关LeetCode题:cookie
122. Best Time to Buy and Sell Stock II 题解app
1090. Largest Values From Labels 题解spa
984. String Without AAA or BBB 题解
但一些问题不那么直观,须要深一层考虑局部最优的策略,例如 LeetCode题目 55. Jump Game:
// 55. Jump Game bool canJump(vector<int>& nums) { int res=0; for(int i=0;i<=res;i++){ res=max(res,i+nums[i]); if(res>=nums.size()-1) return true; } return false; }
以上每轮更新最远能够到达的位置。
相关LeetCode题:
861. Score After Flipping Matrix 题解
921. Minimum Add to Make Parentheses Valid 题解
1053. Previous Permutation With One Swap 题解
贪心与优先级队列
一些贪心策略是每轮获取极值处理,这时能够借助于优先级队列,关于优先级队列详见:
算法与数据结构基础 - 堆(Heap)和优先级队列(Priority Queue)
相关LeetCode题:
1005. Maximize Sum Of Array After K Negations 题解
1167. Minimum Cost to Connect Sticks 题解
358. Rearrange String k Distance Apart 题解
贪心与排序
相似地,也能够经过排序得到极值以用于贪心策略,关于排序详见:
相关LeetCode题:
406. Queue Reconstruction by Height 题解
452. Minimum Number of Arrows to Burst Balloons 题解
435. Non-overlapping Intervals 题解
优先级队列和排序还能够一块儿应用于贪心策略(这类贪心策略我称之为多层贪心策略),例如针对二维数据,先对第一维排序、而后经过优先级队列对第二维取极值。