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

相关推荐
CoovallyAIHub2 小时前
181小时视频丢给GPT-5,准确率只有15%——南大联合NVIDIA等五校发布多模态终身理解数据集
深度学习·算法·计算机视觉
CoovallyAIHub3 小时前
CVPR 2026 | GS-CLIP:3D几何先验+双流视觉融合,零样本工业缺陷检测新SOTA,四大3D工业数据集全面领先!
深度学习·算法·计算机视觉
xlp666hub3 小时前
Leetcode 第三题:用C++解决最长连续序列
c++·leetcode
有意义5 小时前
深度拆解分割等和子集:一维DP数组与倒序遍历的本质
前端·算法·面试
xlp666hub6 小时前
Leetcode第二题:用 C++ 解决字母异位词分组
c++·leetcode
用户726876103376 小时前
解放双手的健身助手:基于 Rokid AR 眼镜的运动计时应用
算法
Wect7 小时前
LeetCode 17. 电话号码的字母组合:回溯算法入门实战
前端·算法·typescript
xlp666hub1 天前
Leetcode第一题:用C++解决两数之和问题
c++·leetcode
ZhengEnCi1 天前
08c. 检索算法与策略-混合检索
后端·python·算法
程序员小崔日记1 天前
大三备战考研 + 找实习:我整理了 20 道必会的时间复杂度题(建议收藏)
算法·408·计算机考研