理论基础
特点:局部最优->整体最优,想不到反例就可以拿来用
455 分发饼干
题目链接
思路
要尽可能多的满足,就要先满足胃口小的孩子。先对孩子排序,对于每一个孩子,找一块刚好大于等于他胃口的饼干。
cpp
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int count = 0;
int s_start = 0;
for(int i = 0; i < g.size();i++)
{
bool is_satisfied = false;
for(int j = s_start; j < s.size(); j++)
{
if(s[j] >= g[i])
{
is_satisfied = true;
count++;
s_start = j + 1; //下一次开始位置从当前满足的下一条位置开始
break;
}
}
if(is_satisfied == false) //后面的都无法满足,停止向后遍历
{
break;
}
}
return count;
}
};
//优化:不需要遍历两个数组,用一个慢指针控制一遍移动就可以,实际上上面并没有二重循环
376 摆动序列
题目链接
思路
如何让整体序列最长?注意题目描述可以删除节点来使最长。那么什么情况下局部最优呢?对于一个非递增/递减序列,可以取两边节点,删掉中间节点,即序列中的每一个元素尽可能达到峰值。

这里有几个情况:
- 平坡:只留一个
- 单调坡:删除中间节点
- 单调坡中出现平坡:删除中间节点
文章详解
cpp
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size() <= 1) return 1;
int curDiff = 0;
int preDiff = 0;
int count = 1;
for(int i = 0; i < nums.size() - 1; i++)
{
curDiff = nums[i+1] - nums[i];
if((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0))
{
count++;
preDiff = curDiff;
}
}
return count;
}
};
53 最大子序和
题目链接
思路
局部最优:当前序列和大于0,否则舍弃,因为会拖累总和,从下一个位置开始
全局最优:子序最大
文章详解
cpp
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int result = INT_MIN;
int tmp = 0;
for(int i = 0; i < nums.size();i++)
{
tmp += nums[i];
if(tmp > result)
{
result = tmp;
}
if(tmp < 0) tmp = 0;
}
return result;
}
};