分发饼干
思路:把最大的饼干分给胃口最大的人,所以可以先对两个数组进行排序,然后用双指针从后往前依次比较。如果饼干能成功头尾,就让饼干组的指针往前移
int bisc=s.size()-1;
int i=g.size()-1;//小孩组
for(;i>=0;i--){
if(s[bisc]>=g[i])
count++;bisc--;
}
摆动序列
题目
最开始这题我的思路是用双指针pre和cur,
int cha=nums[cur]-nums[pre];
如果cha>0,就一直往前找,找到这单调递增的顶点,
然后把它赋给pre,这样pre就是图中虚线的部分。
if(cha>0){
count++;
while(cur<nums.size()-1&&nums[cur+1]>nums[cur]){
cur++;//这样刚好停在顶峰
}
pre=cur;
}
cha<0同理,然后在for循环里每次cur++;指向下一个,这样即使是碰到相同的也可以直接跳过。
问题来了
如果这样写,碰到[1,2,2,2,3]的数据时,摆动序列长度应该是2的,但是pre=1,cur=2时count++;然后到pre=2,cur=3时仍然是count++;所以应该考虑定义两个差值,一个记录前一个差值,一个记录当前的差值,如果这两个差值异号才能count++
int prediff=0;
int pre=0;
for(int cur=1;cur<nums.size();cur++){
int curdiff=nums[cur]-nums[pre];
if(cha>0){
if(prediff*curdiff<=0)
count++;
while(cur<nums.size()-1&&nums[cur+1]>nums[cur]){
cur++;//这样刚好停在顶峰
}
pre=cur;
}
.....
}
另一种写法
算一个点的左边差值和右边差值,如果左边和右边异号则结果++;
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int count=1;
int prediff=0;
for(int i=0;i<nums.size()-1;i++){
int curdiff=nums[i+1]-nums[i];
if(prediff<=0&&curdiff>0){
count++;
prediff=curdiff;
}
else if(prediff>=0&&curdiff<0){
count++;
prediff=curdiff;
}
}
return count;
}
};
只用在坡度有变化时更新就行了
最大自序和
题目
最开始我想的是从两边找连续的最小数组和,然后用总和减去他们就是答案,但事实上这两个数组可能会有交叉的部分,1,-1,1;
而且要分类讨论的情况还很多,非常之麻烦。
其实只用在一段数组它的sum<0时,果断把它甩走,然后从下一位开始重新计数就行,因为它对于之后的部分,不管怎样都是起到一个拖累的作用。
int sum=0;
int ans=nums[0];
for(int i=0;i<nums.size();i++){
sum+=nums[i];
ans=max(ans,sum);
if(sum<0)
sum=0;
}
return ans;