贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。
不用花心思去研究其规律, 没有思路就立刻看题解。
基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。
学完贪心之后再去看动态规划,就会了解贪心和动规的区别。
理论基础
455.分发饼干
// 思路1:优先考虑饼干,小饼干先喂饱小胃口 public int findContentChildren(int[] g, int[] s) { Arrays.sort(g); Arrays.sort(s); int start = 0; for (int i = 0; i < s.length && start < g.length; i++) { if (s[i] >= g[start]) { start++; } } return start; }
// 思路2:优先考虑胃口,先喂饱大胃口 public int findContentChildren(int[] g, int[] s) { Arrays.sort(g); Arrays.sort(s); int count = 0; int start = s.length - 1; // 遍历胃口 for (int index = g.length - 1; index >= 0; index--) { if(start >= 0 && g[index] <= s[start]) { start--; count++; } } return count; }
376. 摆动序列
public int wiggleMaxLength(int[] nums) { if (nums.length <= 1) { return nums.length; } int curDiff = 0; int preDiff = 0; int count = 1; for (int i = 1; i < nums.length; i++) { //得到当前差值 curDiff = nums[i] - nums[i - 1]; //如果当前差值和上一个差值为一正一负 //等于0的情况表示初始时的preDiff if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) { count++; preDiff = curDiff; } } return count; }
53. 最大子序和
可以用dp,也可以用贪心
public int maxSubArray(int[] nums) { if (nums.length == 1){ return nums[0]; } int sum = Integer.MIN_VALUE; int count = 0; for (int i = 0; i < nums.length; i++){ count += nums[i]; sum = Math.max(sum, count); // 取区间累计的最大值(相当于不断确定最大子序终止位置) if (count <= 0){ count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和 } } return sum; }