贪心算法
- 贪心算法 greedy,局部最优 → \to → 全局最优
- 思考是否可以使用贪心算法——看看是否可以举出反例
贪心的解题步骤:
- 将问题拆分成几个子问题
- 找greedy的解决方法,解出每个子问题的最优解
- 通过局部最优推导出 → \to → 全局最优
leetcode 455
题目链接
分饼干——要求满足的孩子个数最大
思路:
- 经典贪心题目
- 优先考虑满足胃口小的孩子——小饼干给小朋友
- 优先使用大饼干——大饼干给大朋友
∵ \because ∵ 饼干只能一个一个给,不能分割
class Solution {
public int findContentChildren(int[] g, int[] s) {
int num = 0;
Arrays.sort(g);
Arrays.sort(s);
int j = 0;
for (int i = 0; i < s.length; ++i) {
if (j < g.length && g[j] <= s[i]) {
++num;
++j;
}
}
return num;
}
}
leetcode 376
题目链接
摆动序列 wiggle subsequence
思路:
- 因为是找可以构成摆动的子序列
- 利用贪心思想,找”峰值“
- 上下坡,中间有平坡
- 单调的坡,中间有平坡
题解
class Solution {
public int wiggleMaxLength(int[] nums) {
if (nums.length < 2)
return nums.length;
int cur = 0;
int pre = 0;
int num = 1;
for (int i = 1; i < nums.length; ++i) {
cur = nums[i] - nums[i - 1];
if ((cur > 0 && pre <= 0) || (cur < 0 && pre >= 0)) {
++num;
pre = cur;
}
}
return num;
}
}
leetcode 53
题目链接
最大子数组和
思路:
- 局部最优
- 当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
- 全局最优
- 选取最大“连续和”
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length < 2)
return nums[0];
int sum = 0, max = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; ++i) {
sum += nums[i];
max = (sum > max) ? sum : max;
if (sum < 0)
sum = 0;
}
return max;
}
}