• 贪心算法总结


    1. 单调递增的数字

    先来看第一种思路:

    这种会超时,我们想想一下贪心的策略

    直接上代码:

    1. class Solution {
    2. public:
    3. int monotoneIncreasingDigits(int n) {
    4. string str = to_string(n); // 把数组转化为字符串
    5. int pos = 0;
    6. while(pos + 1 < str.size() && str[pos] <= str[pos + 1])
    7. {
    8. pos++;
    9. }
    10. // 走到这里两种情况
    11. // 1.一直走到尾都是递增的
    12. if(pos + 1 == str.size()) return n;
    13. // 2.走到中途停下来
    14. while(pos - 1 >= 0 && str[pos - 1] == str[pos])
    15. {
    16. pos--;
    17. }
    18. str[pos]--;
    19. for(int i = pos + 1; i < str.size(); i++)
    20. {
    21. str[i] = '9';
    22. }
    23. return stoi(str);
    24. }
    25. };

    2. 坏了的计算器

    直接上思路:

    直接上代码:

    1. class Solution {
    2. public:
    3. int brokenCalc(int startValue, int target) {
    4. int ret = 0;
    5. while(startValue < target)
    6. {
    7. if(target & 1 == 1) //奇数
    8. {
    9. target += 1;
    10. }
    11. else
    12. {
    13. target /= 2;
    14. }
    15. ret++;
    16. }
    17. return ret - target + startValue;;
    18. }
    19. };

    3. 合并区间

    直接上思路:

    上代码:

    1. class Solution {
    2. public:
    3. vectorint>> merge(vectorint>>& intervals) {
    4. // 先对照左端点排序
    5. sort(intervals.begin(), intervals.end());
    6. // 合并区间
    7. int left = intervals[0][0];
    8. int right = intervals[0][1];
    9. vectorint>> ret;
    10. for(int i = 1; i < intervals.size(); i++)
    11. {
    12. int a = intervals[i][0];
    13. int b = intervals[i][1];
    14. if(a <= right) // 有重叠部分
    15. {
    16. right = max(right, b); // 求并集
    17. }
    18. else
    19. {
    20. ret.push_back({left, right});
    21. left = a;
    22. right = b;
    23. }
    24. }
    25. ret.push_back({left,right});
    26. return ret;
    27. }
    28. };

    4. 无重叠区间

    直接上思路:

    直接来写代码:

    1. class Solution {
    2. public:
    3. int eraseOverlapIntervals(vectorint>>& intervals) {
    4. sort(intervals.begin(),intervals.end()); // 左端点排序
    5. int right = intervals[0][1];
    6. int ret = 0;
    7. // 移除区间
    8. for(int i = 1; i < intervals.size(); i++)
    9. {
    10. int a = intervals[i][0];
    11. int b = intervals[i][1];
    12. if(right > a) // 重叠
    13. {
    14. right = min(right, b); // 贪心:删除右端点最大的区间
    15. ret++;
    16. }
    17. else
    18. {
    19. right = b;
    20. }
    21. }
    22. return ret;
    23. }
    24. };

    5. 用最少数量的箭引爆气球

    我们会发现这个题目依然是一个区间问题,所以做法依然是先对左端点排序,然后再想出一个贪心策略即可,我们只需要最少的弓箭数,那么一支箭应该引爆更多的气球,将两两互相重叠的所有区间都拿出来引爆。

    直接上代码:

    1. class Solution {
    2. public:
    3. int findMinArrowShots(vectorint>>& points) {
    4. // 按照左端点进行排序
    5. sort(points.begin(), points.end());
    6. int right = points[0][1];
    7. int ret = 1;
    8. // 求互相重叠区间的数量
    9. for(int i = 1; i < points.size(); i++)
    10. {
    11. int a = points[i][0];
    12. int b = points[i][1];
    13. if(a <= right) // 有重叠部分
    14. {
    15. right = min(right, b);
    16. }
    17. else
    18. {
    19. right = b;
    20. ret++; // 此时无重复区间,需要再来一支箭
    21. }
    22. }
    23. return ret;
    24. }
    25. };

  • 相关阅读:
    HTML和CSS
    企业微信hook接口协议,ipad协议http,发送小程序
    100天精通Python(可视化篇)——第100天:Pyecharts绘制多种炫酷漏斗图参数说明+代码实战
    Python中的列表(清晰易懂)
    树莓派系统文件解析
    文本处理三剑客之 sed 流编辑器(高级部分)
    Mysql查询操作 联合查询 子查询
    【SpringBoot】SpringBoot实现基本的区块链的步骤与代码
    Kettle BIGNUMBER & TIMESTAMP 类型格式处理
    Ghidra逆向工具之旅与二进制代码分析【2】
  • 原文地址:https://blog.csdn.net/qq_64446981/article/details/139346190