● 455.分发饼干
遍历小孩胃口,对每个小孩,选择符合他胃口的最小尺寸的饼干。这里如果g不排序,index每轮都要从0开始,时间复杂度会到平方。
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
int count=0;
sort(s.begin(),s.end());
sort(g.begin(),g.end());
int index=0;
for(int i=0;i<g.size();++i){
for(;index<s.size()&&g[i]>s[index];++index);//s[index]:满足胃口最小的饼干
if(index==s.size())break;
index++;
count++;
}
return count;
}
};
● 376. 摆动序列
峰值是摆动的不能删。这题就是统计所有峰值(两边的两个元素和中间的极值)。
自己没看随想录写了一下。pre统计相邻前一个间隔的差值,p统计当前间隔的差值。如果p==0,或者前后两个间隔差值符号相反count不会++。但是有2个数据很多的例子不能通过:
class Solution {//不可通过
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size()==1)return 1;
if(nums.size()==2&&nums[0]==nums[1])return 1;//2个相同元素
int pre=nums[1]-nums[0];//前一个间隔的差值
int count=(pre==0)?1:2;//nums前两个里面的count
for(int i=2;i<nums.size();++i){
int p=nums[i]-nums[i-1];
if(p==0||p * pre < 0){ //不应该统计
pre=p; //wrong
continue;
}
else{
pre=p;
count++;
}
}
return count;
}
};
发现问题:我是把不符合这四种情况的直接跳过,p==0(目前平缓)和p*pre>0(单调增或单调减)是不应该统计的情况。我这里错在,不应该统计的情况下,不能把pre赋值为p,直接continue就行,这个pre应该指向上一个不平缓的间隔,不是每一次都要更新。
pre不一定得是p的前一个相邻的间隔,而是应该是p的前一个不平缓的间隔(上升或者下降),比如这个例子,如果pre一直在p的前面,到3的时候p>0、pre=0就会统计上,但是这个正确答案应该是 最后一个不统计,所以p(3-2)应该和(2-1,p的前一个不平缓的间隔)比,而不是相邻前一个。
改一改代码如下(可通过),这样pre永远不会赋值为0,所以一直是p的前一个不平缓间隔的差值。
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size()==1)return 1;
int pre=nums[1]-nums[0];//前一个不平缓间隔的差值,不是相邻!!
int count=(pre==0)?1:2;//先统计nums前两个元素的count
for(int i=2;i<nums.size();++i){
int p=nums[i]-nums[i-1];
if(p==0||p * pre > 0){ //不统计的情况
//pre=p; //pre不会=0
continue;
}
pre=p;
count++;
}
return count;
}
};
所以严格单调递减/严格单调递增和中间有相同元素的递增或者递减都会跳过,这样把所有峰值都统计到了。下面图里面没有峰值,所以不会统计。
● 53. 最大子序和
暴力超时了。
自己想的:sum跳过负数nums[i];正确的:nums[i]跳过负数sum。所以i从左往右:一旦sum为负数,drop it。即sum置零,重新求和。就是把nums[i]作为基准量,sum作为偏移量,抛弃会使得nums[i]变小的sum(小于0的)。每个i都会记录下max_sum,选出最大sum
和上一道题代码都短,就是想不到这种思路。
如果都是负数,可以在循环前求出序列的最大值,然后返回,这样时间开销稍微大一点。
或者在循环的时候,先比较出max_sum,再判断sum是不是负数是否要置零,这样max_sum放的就是最大值,无论这个nums是只有负数还是正负数都有
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max_sum=INT_MIN;
int sum=0;
for(int i=0;i<nums.size();++i){
if(sum<0){
sum=0; //判断sum要不要置零(重新开始)
}
sum+=nums[i]; //sum:某个元素到nums[i]的和
if(sum>max_sum)max_sum=sum; //每个元素i都对应一个sum,都与max_sum比较以更新max_sum
}
return max_sum;
}
};