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

代码随想录算法训练营第二十七天任务

56. 合并区间

題目链接:56. 合并区间

思路:当遇到intervalsi0 > end 将之前的start, end存储起来,更新start,end; 当重叠时,更新end.

cpp 复制代码
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());
        int start = intervals[0][0];
        int end = intervals[0][1];
        vector<vector<int>> res;
        for (int i = 1; i < intervals.size(); ++i) {
            if (intervals[i][0] > end) {
                res.push_back({start, end});
                start = intervals[i][0];
            }
            if (intervals[i][1] > end) {
                end = intervals[i][1];
            } 
        }
        res.push_back({start, end});   // 最后一个区间数组
        return res;
    }
};

时间复杂度:O(n log n)

空间复杂度:O(n) 排序

738.单调递增的数字

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

看题解了,从后往前遍历。

让我想起了135. 分发糖果这道题从右向左遍历时的情景。

cpp 复制代码
class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string strNum = to_string(n);
        int flag = strNum.size();   // 记录哪一位是从 9 开始的. eg: 1000   不能初始化0或者-1,
        for (int i = strNum.size() - 1; i >= 1; --i) {
            if (strNum[i - 1] > strNum[i]) {   // 出现递减
                strNum[i - 1]--;
                strNum[i] = '9';
                flag = i;
            }
        }
        for (int i = flag + 1; i < strNum.size(); ++i) {
            strNum[i] = '9';
        }
        return atoi(strNum.c_str());
    }
};

时间复杂度:O(n)

空间复杂度:O(n) 字符串空间

968.监控二叉树

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

这道题相当困难。看题解了。

自己再写一下思路,加强理解。

首先是叶子节点肯定不放摄像头,这样能保证最少的摄像头数量。(叶子节点是指数级别的增长)

在层上,每隔两个放一个摄像头

树的遍历方式:后序遍历(左右后)

对于监控二叉树的节点,有三种状态:有摄像头,有覆盖,无覆盖。

用1表示有摄像头

用2表示有覆盖

用3表示无覆盖

如果遇到空节点,肯定不是有摄像头,如果是无覆盖,那么叶子节点就要有摄像头(想象一个节点 左孩子 和 右孩子 只有其中一个),所以空节点的状态应该是有覆盖。

cpp 复制代码
/*
    用 1 表示有摄像头
    用 2 表示有覆盖
    用 3 表示无覆盖 : 叶子节点,父节点有摄像头
 */
class Solution {
    int result = 0;
    int traversal(TreeNode* cur) {
        if (cur == nullptr) return 2;  // 空节点表示有覆盖。
        int left = traversal(cur->left);
        int right = traversal(cur->right);

        // 左右节点都有覆盖
        if (left == 2 && right == 2) return 3;

        // 左右节点至少有一个是无覆盖,父节点就要放摄像头
        if (left == 3 || right == 3) {
            result++;
            return 1;
        }

        // 左右节点任一一个有摄像头, 父节点就是有覆盖
        if (left == 1 || right == 1) return 2;
        
        return -1;  // 逻辑不会走到这里,只是函数需要个返回值。
    }

public:
    int minCameraCover(TreeNode* root) {
        if (traversal(root) == 3) {   // 如果头节点无覆盖,就需要加摄像头
            result++;
        }
        return result;
    }
};

这道题有意思。

时间复杂度:O(n) 需遍历每个节点

空间复杂度:O(n) 递归栈深度

相关推荐
fpcc1 小时前
c++编程实践—堆和栈越界调试
c++
yi0111 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
weiabc3 小时前
MSYS2 UCRT64 + g++ C++ 中文输出乱码 完整全过程
c++
灯澜忆梦4 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
小蒋观天下4 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J4 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛4 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有5 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu1111115 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS5 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密