455.分发饼干
注意事项
是先遍历的胃口,在遍历的饼干
不可以先遍历 饼干,再遍历胃口。
外面的 for 是里的下标 i 是固定移动的,而 if 里面的下标 index 是符合条件才移动的。
如果 for 控制的是饼干, if 控制胃口,就是出现如下情况 :
if 里的 index 指向 胃口 10, for 里的 i 指向饼干 9,因为 饼干 9 满足不了 胃口 10,所以 i 持续向前移动,而 index 走不到s[index] >= g[i]
的逻辑,所以 index 不会移动,那么当 i 持续向前移动,最后所有的饼干都匹配不上。
所以 一定要 for 控制 胃口,里面的 if 控制饼干。
反过来(错误)的图:
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int res = 0;
int index=s.size()-1; // 饼干数组的下标
for (int i=g.size()-1; i>=0; i--) {
if (index>=0 && s[index]>=g[i]){
res++;
index--;
}
}
return res;
}
};
376. 摆动序列
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size()==1){
return 1;
}
int prediff = 0;
int curdiff = 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;
}
};
53. 最大子序和
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
全局最优:选取最大“连续和”
遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。
这相当于是暴力解法中的不断调整最大子序和区间的起始位置。
区间的终止位置,其实就是如果 count 取到最大值了,及时记录下来了。
if (count > result) result = count;
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int result = INT32_MIN;
int count = 0; // 记录连续和
for (int i=0; i<nums.size(); i++){ // 遍历
count += nums[i];
if (count > result){ // 记录最大值(相当于不断确定最大子序终止位置)
result = count;
}
// 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
if (count < 0) count = 0; // 下个nums[i]成为新起点
}
return result;
}
};