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

相关推荐
MadPrinter2 小时前
Python 异步爬虫实战:FindQC 商品数据爬取系统完整教程
爬虫·python·算法·自动化
郝学胜-神的一滴2 小时前
Effective Modern C++ 条款36:如果有异步的必要请指定std::launch::async
开发语言·数据结构·c++·算法
小此方2 小时前
Re:从零开始的 C++ STL篇(六)一篇文章彻底掌握C++stack&queue&deque&priority_queue
开发语言·数据结构·c++·算法·stl
0 0 02 小时前
CCF-CSP 40-2 数字变换(transform)【C++】考点:预处理
开发语言·c++·算法
香芋Yu2 小时前
【强化学习教程——01_强化学习基石】第06章_Q-Learning与SARSA
人工智能·算法·强化学习·rl·sarsa·q-learning
回敲代码的猴子2 小时前
2月15日打卡
数据结构·算法
菜鸡儿齐3 小时前
leetcode-和为k的子数组
java·算法·leetcode
踩坑记录3 小时前
leetcode hot100 437. 路径总和 III medium 前缀和 DFS
leetcode
3 小时前
2.15最大效益,螺旋方阵,方块转化
算法