贪心法:遵循某种规律,不断贪心选取当前最优策略的算法设计。
1、分糖果 LC455
题目:一些孩子和糖果,孩子有需求因子g,糖果有大小s,s>=g时表示糖果可以满足孩子。假设g=[5,10,2,9,15,9],s=[6,1,2,10,3,8],求糖果可以满足多少孩子?
分析:先排序,对需求和糖果的大小进行排序,g=[2,5,9,9,10,15],s=[1,3,6,8,20]。
①某个糖果不能满足某个孩子,则糖果无法满足需求因子更大的孩子。
②可以用更小的糖果满足时,没必要用更大的糖果,保留大糖果满足大需求。
③需求因子小更容易满足,所以优先从需求最小的孩子进行尝试。
注意:边界越界
代码:
public int findContentChildren(int[] g, int[] s) {
int child = 0;
int candy = 0;
Arrays.sort(g);
Arrays.sort(s);
while (child < g.length && candy < s.length) {
if (g[child] <= s[candy]) {
child++;
}
candy++;
}
return child;
}
2、最长摇摆子序列 LC376
题目:相邻的两个元素的差正负(负正)交替出现,则被称为摇摆序列,长度<2直接为摇摆序列,求数组的最长摇摆子序列。
分析:如[1,3,1,3]是一个摇摆序列,长度为4,[1,7,5,10,13,15,10,5,16,8]的最长摇摆子序列[1,7,5,15,5,16,8]。再次强调:子序列不一定连续!其实很容易想到极值,[5,10,13,15]在区间内连续递增,则选择5,15来保证15更大,5更小,子序列更长。
代码:
public int wiggleMaxLength(int[] nums) {
int n = nums.length;
if (n < 2) {
return n;
}
int up = 1;
int down = 1;
for (int i = 1; i < n; i++) {
if (nums[i] > nums[i - 1]) {
up = down + 1;
}
if (nums[i] < nums[i - 1]) {
down = up + 1;
}
}
return Math.max(up, down);
}