代码随想录算法训练营第三十一天|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)

相关推荐
wabs6665 小时前
关于哈希表【力扣15.三数之和的思考】
数据结构·算法·leetcode·散列表·哈希表·三数之和
退休倒计时5 小时前
【每日一题】LeetCode 88. 合并两个有序数组 TypeScript
算法·leetcode·职场和发展·typescript
键盘会跳舞5 小时前
C++:函数对象与 std::function 源码级深度拆解——泛型算法的策略内核与可调用对象统一封装
c++·算法·仿函数
手写码匠5 小时前
华为云Flexus+DeepSeek征文|Agent 评测体系实战:用 DeepSeek-R1 当裁判,打造 Dify Agent 的自动化回归测试流水线
人工智能·深度学习·算法·aigc
LONGZETECH5 小时前
无人机实训高成本痛点解法:虚拟仿真实现 70% 耗材损耗下降
大数据·算法·unity·架构·无人机
不会就选b5 小时前
算法日常・每日刷题--<队列,宽搜>4
算法
码字的特恩6 小时前
微软确认暂不为 Windows 11 加入透明效果自定义功能,建议用户使用第三方工具
人工智能·windows·算法·microsoft·计算机·大模型·编程
星轨初途6 小时前
LeetCode 热题 100——day10 和为 K 的子数组
开发语言·c++·算法·leetcode
数模竞赛Paid answer6 小时前
2021年深圳杯数学建模C题配电网可靠性和故障软自愈研究解题全过程论文及程序
算法·数学建模·数据分析·深圳杯
有点。6 小时前
C++广度优先搜索(二)-练习题
c++·算法·宽度优先