[刷题笔记34 贪心算法 part 03]

贪心算法

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

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

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

法1:贪心

    static bool cmp(int a,int b){
        if (abs(a) >abs(b))
            return true;
        return false;
    }
    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){
                k--;
                nums[i] *= -1;
            }
        }

        int ans = 0;
        if (k % 2 == 1) nums[nums.size() - 1] *= -1;

        for (const auto &item: nums)
            ans += item;
        return ans;
    }

134. 加油站

134. 加油站
法1:贪心

      int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        //暴力模拟
        //贪心算法
        /**
         * 情况一:如果gas的总和小于cost总和,
         * 那么无论从哪里出发,一定是跑不了一圈的
           情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,
         i从0开始计算累加到最后一站,如果累加没有出现负数,
         说明从0出发,油就没有断过,那么0就是起点。
           情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,
         看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。
         */

         int cur_sum = 0;
//        rest[i] = gas[i]-cost[i]
        int min = INT_MAX; // 从起点出发,油箱里的油量最小值
        for (int i = 0; i < cost.size(); ++i) {
            int rest = gas[i] - cost[i];
            cur_sum += rest;
            if (min >= cur_sum)
                min = cur_sum;
        }
        if (cur_sum < 0)return -1;



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

135. 分发糖果

135. 分发糖果

法1:贪心

        int candy(vector<int>& ratings) {
        vector<int> candies(ratings.size(),1);
        int sum = 0;
        for (int i = 1; i < ratings.size(); ++i) {
            if (ratings[i] > ratings[i - 1])
                candies[i] = candies[i - 1] + 1;
        }

        /**
         * 所以确定左孩子大于右孩子的情况一定要从后向前遍历!
        如果 ratings[i] > ratings[i + 1],此时candyVec[i](
         第i个小孩的糖果数量)就有两个选择了,
         一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),
         一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。
         */
        for (int i = ratings.size()-1; i >= 1; i--) {
            if (ratings[i - 1] > ratings[i] )
                candies[i - 1] = max(candies[i - 1],candies[i] + 1);
        }
        for (const auto &item: candies)
            sum += item;
        return sum;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值