Day28||● 1005.K次取反后最大化的数组和 ● 134. 加油站● 135. 分发糖果

● 1005.K次取反后最大化的数组和

首先是我的错误写法:

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end());
        bool flag=false;
        for(int i=0;i<k&&i<nums.size();i++)
        {
            nums[i]=-nums[i];
            if(nums[i]==0)
            {
                flag=true;
                break;
            }
        }
        k-=nums.size();
       while(k>0&&flag!=true)
       {
            sort(nums.begin(),nums.end());

           for(int i=0;i<k&&i<nums.size();i++)
          {
            nums[i]=-nums[i];
          }
          k-=nums.size();

       }
       int sum=0;
       for(int i=0;i<nums.size();i++)
       {
          sum+=nums[i];
       }

       return sum;
    

    }
};

错误的原因是没有考虑到可以在同一个数上进行反转,如果都是正数就可能反转所有。

正确的贪心:

先反转绝对值大的负数再反转绝对值小的正数!

class Solution {
public:
static bool cmp(int a,int b)
{
    return abs(a)>abs(b);
}
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end(),cmp);
        for(int i=0;i<nums.size();i++)
        {
            if(nums[i]<0&&k>0)
            {
              nums[i]=-nums[i];
              k--;
            }
            

        }
        if(k>0&&k%2==1)
        {
            nums[nums.size()-1]=-nums[nums.size()-1];
        }
        int sum=0;
        for(auto it:nums)
        {
            sum+=it;
        }
        return sum;


    }
};

血的教训:

int和unsigned int比较大小,vector的size()函数使用注意事项

首先我们需要知道int与unsigned int进行比较时,会先将int转换为unsigned int进行比较,二者都是正数时没有问题,但是,当int的值为负数时,就会出现-1 > 1的情况!!!!!重点来了,vector 的size()函数返回的就是unsigned int!!!!所以如果有负数比较就会出错!

134. 加油站

这道题还是有一些难度的。上来第一个想法其实就是暴力。遍历从所有点出发的情况。第二种方法是从整体上考虑,分三种情况。也不太算是贪心算法。其实在第三种情况如果在最小min点取值之前没找到可以填平的点,那么其实也就不可能有能够填平的点了。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int cursum=0;
        int min=INT_MAX;
        int mindex;
        for(int i=0;i<gas.size();i++)
        {
            cursum+=gas[i]-cost[i];
            if(cursum<min)
            {
                 min=cursum;
                 mindex=i;

            }
           

        }
        if(cursum<0) return -1;
        if(min>=0) return 0;

        for(int i=gas.size()-1;i>mindex;i--)
        {
           min+=gas[i]-cost[i];
            if(min>=0)
            return i;

        }

        return -1;


    }
};

135. 分发糖果

这道题很难,算法上来说很不好想。主要就是贪心,我们先使得从左往右的右边分数大于左边,再使从右向左的左分数大于右边,且去两种情况最大值来满足。

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candy(ratings.size(),1);
        for(int i=1;i<ratings.size();i++)
        {
            if(ratings[i]>ratings[i-1])
            candy[i]=candy[i-1]+1;
        }
        for(int i=ratings.size()-2;i>=0;i--)
        {
            if(ratings[i]>ratings[i+1])
            {
                candy[i]=max(candy[i+1]+1,candy[i]);
            }
        }
        int sum=0;
        for(auto it:candy)
        {
               sum+=it;
        }
        return sum;

    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值