455. Assign Cookies 分发饼干
解题思路:按照规则,为了找到全局最优解,在每一次发放饼干时要尽量不能造成饼干的浪费,我们应该把最大的饼干分给胃口最大的孩子,这个就是局部最优解。把两个列表从小到大排序,从后边最大的饼干开始遍历,同时喂给最大胃口的孩子,直到无法满足或全部发完。
class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int count = 0;
int idx = s.length - 1; // 饼干的idx
// 基于胃口遍历
for (int i = g.length - 1; i >= 0; i--) {
if (idx >= 0 && s[idx] >= g[i]) {
count++;
idx--;
}
}
return count;
}
}
376. 摆动序列
解题思路:由于这道题只需要返回摆动的次数,那么我们可以在遍历过程中只判断当前是不是摆动点,如果是的话就对结果做+1的操作。需要注意几个特殊情况:1. 上下坡之间存在平坡 2. 单调递增/递减的时候存在平坡。
class Solution {
public int wiggleMaxLength(int[] nums) {
if (nums.length <= 1) return nums.length;
int preDiff = 0;
int curDiff = 0;
int count = 1; // 默认最右边有一个摆动
for (int i = 0; i < nums.length - 1; i++) {
curDiff = nums[i+1] - nums[i];
if ((preDiff >= 0 && curDiff < 0)
||(preDiff <= 0 && curDiff > 0)) {
count++;
preDiff = curDiff;//只有摆动的时候更新pre
//防止单调中存在平坡多统计的情况
}//上下摆动(pre等于的情况就是平坡后上升/下降的点)
}
return count;
}
}
53. 最大子序和
解题思路:在这题中我们可以发现局部最优是当出现一段连续和为负数的情况,那么这个时候应该直接抛弃前面的子数组,因为这样再加下去只会让下一个数更小,应该由下一个新的数作为新的起点。同理可得,如果当前的连续和只要依然还是正数的话就要一直保留,因为正数不管是大是小对于后面的数都是有增大作用的。由于本题只需要返回最大子数组和,我们只需要不断追踪当前的子数组和并且当和为负数的时候重新开始计算。
class Solution {
public int maxSubArray(int[] nums) {
//greedy
int res = Integer.MIN_VALUE;
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
if (sum > res) res = sum;
if (sum < 0) sum = 0; //reset
}
return res;
}
}