代码随想录算法训练营第三十四天 | 1005.K次取反后最大化的数组和、134. 加油站、135. 分发糖果

文章介绍了如何通过贪心算法解决LeetCode中的三个问题:1005.K次取反后最大化数组和、134.加油站的燃油规划和135.分发糖果,强调了合理的策略和自定义比较规则在求解过程中的重要性。
摘要由CSDN通过智能技术生成

题目链接:1005.K次取反后最大化的数组和

文章讲解:代码随想录 1005.K次取反后最大化的数组和讲解

视频讲解:贪心算法,这不就是常识?还能叫贪心?LeetCode:1005.K次取反后最大化的数组和

思路和解法

题目:
给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组:

选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
重复这个过程恰好 k 次。可以多次选择同一个下标 i 。

以这种方式修改数组后,返回数组 可能的最大和 。
想法:
见注释,思路写的很详细了,把每一步写代码时的思考都写了。

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);
        //遍历整个数组 当遇到负数且k大于零时 翻转一下符号

        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] < 0 && k > 0) {
                nums[i] *= -1;
                k--;
            }
        }
        //如果k还大于0 就反复翻转最小的非负数
        // while (K > 0) {
        //     nums[nums.size() - 1] *= -1;
        //     K--;
        // }
        //上面不能这样写 会超时 直接通过判断k奇偶
        if (k % 2 == 1) nums[nums.size() - 1] *= -1;
        //求和
        int result = 0;
        for (int i = 0; i < nums.size(); i++) {
            result += nums[i];
        }
        return result;
    }
};

题目链接:134. 加油站

文章讲解:代码随想录 134. 加油站讲解

视频讲解:贪心算法,得这么加油才能跑完全程!LeetCode :134.加油站

思路和解法

题目:
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
想法:
见注释,思路写的很详细了,把每一步写代码时的思考都写了。

class Solution {
public:
    //自己的思路:首先只能从gas>cost的一个加油站出发,否则无法走到下一个加油站
    //如果有多个满足第一个条件的加油站怎么办?要让车里尽可能多地省汽油给后面用,所以从gas和cost差值最大的加油站出发
    //讲解给的思路更简单 但是感觉自己很难想 关键点在于什么时候更新起始下标
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        //记录起始下标
        int start = 0;
        //记录当前区间和
        int curSum = 0;
        //记录消耗总油量
        int totalSum = 0;
        for (int i =0; i < gas.size(); i++) {
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if (curSum < 0) {
                start = i + 1;
                curSum = 0;
            }
        }
        if (totalSum < 0) return -1;
        return start;
    }
};

题目链接:135. 分发糖果

文章讲解:代码随想录 135. 分发糖果讲解

视频讲解:贪心算法,两者兼顾很容易顾此失彼!LeetCode:135.分发糖果

思路和解法

题目:
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
想法:
见注释,思路写的很详细了,把每一步写代码时的思考都写了。

class Solution {
public:
    int candy(vector<int>& ratings) {
        //为了使用更少的糖果,最好肯定是只给一个糖果,先考虑从左向右遍历,如果当前比前一个评分高,那肯定要让糖果数递增+1
        //如果当前评分小于前一个,那就是只给1个,这样做至少可以和前一个比每一个都满足要求
        //然后就会发现如果评分递减,前面的规则就不完善,所以还需要从后向前遍历一遍,同样的规则,这样做可以保证和后一个比都满足要求
        //最后如何处理两次遍历产生冲突的部分呢?为了整体都满足要求,肯定是取糖果数更大的。
        //记录糖果数
        vector<int> candyVec(ratings.size(), 1);
        // 从前向后
        for (int i = 1; i < ratings.size(); i++) {
            if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
        }
        // 从后向前
        for (int i = ratings.size() - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1] ) {
                candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
            }
        }
        // 统计结果
        int result = 0;
        for (int i = 0; i < candyVec.size(); i++) result += candyVec[i];
        return result;
    }
};
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值