455. 分发饼干
思路1
从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。
这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。
class Solution {public int findContentChildren(int[] g, int[] s) {Arrays.sort(g);Arrays.sort(s);int start = s.length-1;//饼干的下标,也是倒的int count = 0;//统计的数量for (int i = g.length-1; i >=0; i--){//从后向前遍历小孩数组,最大的饼干给胃口大的小孩if (start >= 0 && g[i] <= s[start]){start--;count++;}}return count;}}
思路2
小饼干先喂饱小胃口
class Solution {
// 思路1:优先考虑饼干,小饼干先喂饱小胃口
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int start = 0;
int count = 0;
for (int i = 0; i < s.length && start < g.length; i++) {
if (s[i] >= g[start]) {
start++;
count++;
}
}
return count;
}
}
376. 摆动序列
https://www.programmercarl.com/0376.%E6%91%86%E5%8A%A8%E5%BA%8F%E5%88%97.html#%E6%80%9D%E8%B7%AF1-%E8%B4%AA%E5%BF%83%E8%A7%A3%E6%B3%95
思路1(贪心算法)
局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。
整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。
class Solution {
public int wiggleMaxLength(int[] nums) {
if (nums.length <= 1) return nums.length;
int curDiff = 0; // 当前一对差值
int preDiff = 0; // 前一对差值//初始时默认前面有一个
int result = 1; // 记录峰值个数,序列默认序列最右边有一个峰值
for (int i = 0; i < nums.length - 1; i++) {
curDiff = nums[i+1] - nums[i];
if ((curDiff > 0 && preDiff <= 0 )||(preDiff >= 0 && curDiff < 0)){
result++;
preDiff = curDiff;
}
}
return result;
}
}
思路2(动态规划)
待补。。。
53. 最大子数组和

贪心贪的是哪里呢?
如果 -2 1 在一起,计算起点的时候,一定是从1开始计算,因为负数只会拉低总和,这就是贪心贪的地方!
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
全局最优:选取最大“连续和”
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
从代码角度上来讲:遍历nums,从头开始用count累积,如果count一旦加上nums[i]变为负数,那么就应该从nums[i+1]开始从0累积count了,因为已经变为负数的count,只会拖累总和。
这相当于是暴力解法中的不断调整最大子序和区间的起始位置。
class Solution {
public int maxSubArray(int[] nums) {
int count = 0;
int result =Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
count += nums[i];
if (count > result){// 取区间累计的最大值(相当于不断确定最大子序终止位置)
result = count;
}
if (count < 0) count = 0;// 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
}
return result;
}
}
122. 买卖股票的最佳时机 II
class Solution {
public int maxProfit(int[] prices) {
int result = 0;
for (int i = 1; i < prices.length; i++) {
result += Math.max(prices[i] - prices[i-1],0);
}
return result;
}
}
55. 跳跃游戏
https://labuladong.github.io/algo/3/27/102/
这道题表面上不是求最值,但是可以改一改:
请问通过题目中的跳跃规则,最多能跳多远?如果能够越过最后一格,返回 true,否则返回 false。
所以解题关键在于求出能够跳到的最远距离。
boolean canJump(int[] nums) {
int n = nums.length;
int farthest = 0;
for (int i = 0; i < n - 1; i++) {
// 不断计算能跳到的最远距离
farthest = Math.max(farthest, i + nums[i]);
// 可能碰到了 0,卡住跳不动了
if (farthest <= i) {
return false;
}
}
return farthest >= n - 1;
}
45. 跳跃游戏 II

1005. K 次取反后最大化的数组和




