代码随想录算法训练营第三十一天|56. 合并区间 、 738.单调递增的数字、968.监控二叉树

题目链接:56. 合并区间

解题思路:排序 + 贪心

具体思路:

首先处理边界情况,若输入的区间数组为空则直接返回空结果数组,接着将区间数组按左端点升序排序,保证相邻区间的左端点有序,初始化结果数组 ans 并将排序后的第一个区间加入其中,遍历排序后的区间数组,若当前区间的左端点小于等于 ans 最后一个区间的右端点,说明两区间存在重叠,则将 ans 最后一个区间的右端点更新为自身右端点与当前区间右端点的最大值,完成区间合并,若当前区间与 ans 最后一个区间无重叠,则直接将当前区间加入 ans,最终返回的 ans 即为所有合并后的不重叠区间。

具体代码:

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

时间复杂度:O(nlogn)

空间复杂度:O(logn)

题目链接:738.单调递增的数字

解题思路:贪心

具体思路:

首先将整数 n 转换为字符串 str,初始化 flag 为字符串长度,标记需要置为 9 的起始位置,从字符串末尾向前遍历,若发现前一位数字大于当前位,违反递增规则,则将 flag 更新为当前位索引,并将前一位数字减 1,遍历完成后,将 flag 位置到字符串末尾的所有字符统一置为9,保证数值最大,减 1 后的前半段满足递增,后半段置 9 能得到小于等于 n 的最大符合条件数,最后将处理后的字符串转回整数,即为所求的最大单调递增数字。

具体代码:

cpp 复制代码
class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string str = to_string(n);
        int flag = str.size();
        for (int i = str.size() - 1; i > 0; i--) {
            if (str[i - 1] > str[i]) {
                flag = i;
                str[i - 1]--;
            }
        }
        for (int i = flag; i < str.size(); i++) {
            str[i] = '9';
        }
        return stoi(str);
    }
};

时间复杂度:O(n)

空间复杂度:O(n)

题目链接: 968.监控二叉树

解题思路:贪心 + 后序遍历

具体思路:

首先定义全局变量 ans 统计摄像头数量,设计 dfs 函数返回节点的状态,0 表示节点未被覆盖,1 表示节点放置了摄像头,2 表示节点已被覆盖但无摄像头,dfs 函数中,空节点返回 2,视为已覆盖,避免在叶子节点直接放摄像头,是贪心减少数量的关键,先递归处理左、右子节点获取其状态,若左右子节点均为已覆盖,说明当前节点未被覆盖,返回 0,若左右子节点有一个未被覆盖,则在当前节点放置摄像头 ans++,返回 1,若左右子节点有一个放置了摄像头,说明当前节点已被覆盖,返回 2,主函数调用 dfs 处理根节点后,若根节点返回 0 即未被覆盖,需额外在根节点放置一个摄像头,最终返回的 ans 即为覆盖整棵树的最少摄像头数量。

具体代码:

cpp 复制代码
class Solution {
public:
    int ans = 0;
    int dfs(TreeNode* root) {
        if (root == nullptr) return 2;
        int left = dfs(root->left);
        int right = dfs(root->right);
        if (left == 2 && right == 2) return 0;
        if (left == 0 || right == 0) {
            ans++;
            return 1;
        }
        if (left == 1 || right == 1) return 2;
        return -1;
    }
    int minCameraCover(TreeNode* root) {
       if (dfs(root) == 0) ans++;
       return ans;
    }
};

时间复杂度:O(n)

空间复杂度:O(logn)

相关推荐
倒头就睡的小比特20 小时前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!20 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼21 小时前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
m0_547486661 天前
《数据结构教程》全套 PPT课件2026
数据结构
旖旎夜光1 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark1 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her11 天前
并查集-听课笔记
笔记·算法·并查集
码流子1 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven1 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark1 天前
从算法设计模式看编程思维的抽象能力4
算法