1、分发饼干
-
题目链接:455.分发饼干
-
题解:
- 大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。
- 图解:
-
代码如下:
class Solution { public: int findContentChildren(vector<int>& g, vector<int>& s) { int index = 0; // 孩子胃口下标 int success = 0; // 满足条件的情况数量 sort(g.begin(),g.end()); // 给孩子的胃口值从小到大进行排序 sort(s.begin(),s.end()); // 给饼干的尺寸从小到大进行排序 for(int i=0;i<s.size();i++){ // 遍历饼干 if(s[i]>=g[index]){ // 饼干满足孩子的胃口 success++; // 情况满足数量+1 index++; // 换下一个孩子 if(index>=g.size()){ // 如果所有孩子都遍历完了,那么退出循环 break; } } } return success; } };
-
其他
- 其实还有很多种方法,本质上都是一样的思想。这里列举其中一种:先将饼干数组和小孩数组排序。然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。
- 其实还有很多种方法,本质上都是一样的思想。这里列举其中一种:先将饼干数组和小孩数组排序。然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。
2、摆动序列
-
题目链接:376. 摆动序列
-
题解:
- 题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了。
- 在计算是否有峰值的时候,大家知道遍历的下标
i
,计算prediff(nums[i] - nums[i-1])
和curdiff(nums[i+1] - nums[i])
,如果prediff < 0 && curdiff > 0
或者prediff > 0 && curdiff < 0
此时就有波动就需要统计。
- 在计算是否有峰值的时候,大家知道遍历的下标
- 本题还要考虑三种情况。
- 情况一:上下坡中有平坡
- 得出:我们记录峰值的条件应该是:
(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)
,注意,这里添加了=
的情况
- 得出:我们记录峰值的条件应该是:
- 情况一:上下坡中有平坡
- 情况二:数组首尾两端
- 如果数组只有两个元素,那么无法对比
prediff
和curdiff
,为了结果这个问题,可以假设prediff
的初始值为0
。例如:[2,5]
这个数组通过上述方法可以等价为[2,2,5]
- 如果数组只有两个元素,那么无法对比
- 情况三:单调坡度有平坡
- 如果单调坡度上有平坡,那么不能算作是摆动,所以如果我们实时更新了
prediff
,那么就会造成误判。为了防止误判,我们只需要在 这个坡度 摆动变化的时候,更新 prediff 就行
- 如果单调坡度上有平坡,那么不能算作是摆动,所以如果我们实时更新了
- 题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了。
-
代码如下:
class Solution { public: int wiggleMaxLength(vector<int>& nums) { if (nums.size() <= 1) return nums.size(); int curDiff = 0; // 当前一对差值 int preDiff = 0; // 前一对差值 int result = 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)) { result++; } preDiff = curDiff; } return result; } };