代码随想录算法训练营第三十一天 | 贪心算法 part05

56. 合并区间

将当前结果暂存于结果集中,并随着遍历而修改结果集。这样就省去了记录左右边界的问题。

cpp 复制代码
class Solution {
    static bool cmp(vector<int>& a, vector<int>& b) {
        if (a[0] == b[0])
            return a[1] > b[1];
        else 
            return a[0] < b[0];
    }
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        vector<vector<int>> result;
        sort(intervals.begin(), intervals.end(), cmp);
        result.push_back(intervals[0]);
        for (int i = 1; i < intervals.size(); ++i) {
            if (intervals[i][0] <= result.back()[1]) {
                result.back()[1] = max(intervals[i][1], result.back()[1]);
            }
            else {
                result.push_back(intervals[i]);
            }
        }
        return result;
    }
};

738.单调递增的数字

本题的策略是遇到前一位大于后一位的情况,前一位减一,后面的置为9。本题有两个易错点:

  1. 遍历顺序。如果是从前往后遍历,有可能出现332变为329的情况,也就是说后面的符合条件了,但是前面部分不符合条件了。
  2. 要记录最终要修改为9的位置。如果仅仅是将后一位置为9,遇到100就只会得到90而不是99.
cpp 复制代码
class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string result = to_string(n);
        int flag = result.size();
        for (int i = result.size() - 1; i > 0; --i) {
            if (result[i] < result[i - 1]) {
                result[i - 1]--;
                flag = i;
            }
        }
        for (int i = flag; i < result.size(); ++i) {
            result[i] = '9';
        }
        return stoi(result);
    }
};

968.监控二叉树

贪心策略:叶子节点的父节点尽量安装摄像头;每隔两个空节点安装摄像头。

怎么实现呢?

  1. 给每个节点都设置状态,一共有三种状态。
    0:该节点未被覆盖
    1:有摄像头
    2:有覆盖
  2. 确定二叉树遍历顺序。因为要根据子节点的状态来决定是否要安装摄像头,因此采取后序遍历。
  3. 确定终止条件:遇到空节点返回有覆盖2。
  4. 单层处理逻辑:
    1. 左右孩子都有覆盖,返回未覆盖0
    2. 左右孩子有未覆盖,安装摄像头,返回1
    3. 左右孩子有摄像头,返回已覆盖,返回2
    4. 根节点返回未覆盖0,安装摄像头。
cpp 复制代码
class Solution {
public:
    int result = 0;
    // 0:未覆盖
    // 1:有摄像头
    // 2:已覆盖
    int traversal(TreeNode* node) {
        if (node == nullptr)
            return 2;
        
        int left = traversal(node->left);
        int right = traversal(node->right);
        if (left == 2 && right == 2) 
            return 0;
        if (left == 0 || right == 0) {
            result++;
            return 1;
        }
        if (left == 1 || right == 1) {
            return 2;
        }
        return -1;
    }
    int minCameraCover(TreeNode* root) {
        result = 0;
        if (traversal(root) == 0)
            result++;
        return result;
    }
};
相关推荐
知来者逆34 分钟前
计算机视觉——速度与精度的完美结合的实时目标检测算法RF-DETR详解
图像处理·人工智能·深度学习·算法·目标检测·计算机视觉·rf-detr
阿让啊39 分钟前
C语言中操作字节的某一位
c语言·开发语言·数据结构·单片机·算法
এ᭄画画的北北39 分钟前
力扣-160.相交链表
算法·leetcode·链表
爱研究的小陈2 小时前
Day 3:数学基础回顾——线性代数与概率论在AI中的核心作用
算法
渭雨轻尘_学习计算机ing2 小时前
二叉树的最大宽度计算
算法·面试
BB_CC_DD2 小时前
四. 以Annoy算法建树的方式聚类清洗图像数据集,一次建树,无限次聚类搜索,提升聚类搜索效率。(附完整代码)
深度学习·算法·聚类
梁下轻语的秋缘4 小时前
每日c/c++题 备战蓝桥杯 ([洛谷 P1226] 快速幂求模题解)
c++·算法·蓝桥杯
CODE_RabbitV4 小时前
【深度强化学习 DRL 快速实践】逆向强化学习算法 (IRL)
算法
mit6.8244 小时前
[贪心_7] 最优除法 | 跳跃游戏 II | 加油站
数据结构·算法·leetcode
keep intensify4 小时前
通讯录完善版本(详细讲解+源码)
c语言·开发语言·数据结构·算法