贪心算法专题Day22

56. 合并区间

sort排序

遇到能合并的就合并,不能合并的就先将之前合并完的区间push到result里,再更新start和end

处理末尾剩下的最后一个区间

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

738. 单调递增的数字

暴力法:从n开始倒数,判断每个数字是否是合法的

会超时。

cpp 复制代码
bool isVaild(int n){
        int pre = n % 10;
        n /= 10;
        while(n){
            if(n%10 > pre){
                return false;
            }
            pre = n%10;
            n /= 10;
        }
        return true;
    }
    int monotoneIncreasingDigits(int n) {
        for(int i = n; i >= 0; i--){
            if(isVaild(i)){
                return i;
            }
        }
        return 0;
    }

贪心:向前遍历,前一项大于后一项,前一项就减1,后面所有都变成9

cpp 复制代码
    int monotoneIncreasingDigits(int n) {
        string s = to_string(n);
        int len = s.size();
        int flag = len; 

        for (int i = len - 1; i > 0; i--) {
            if (s[i - 1] > s[i]) {
                flag = i;    // 标记从i开始,所有位都要设为9
                s[i - 1]--;  
            }
        }
        for (int i = flag; i < len; i++) {
            s[i] = '9'; 
        }

        return stoi(s);
    }

968. 监控二叉树

后序遍历, 一步一步往上穿

// 0 无覆盖, 1 摄像头, 2 有覆盖

由于叶子结点不能为摄像头(这样有点亏),所以空节点是有覆盖状态,叶子节点就是无覆盖状态了

cpp 复制代码
int count = 0;
    int traversal(TreeNode* cur){
        // 0 无覆盖, 1 摄像头, 2 有覆盖
        if(cur == nullptr){
            return 2;
        }
        int left = traversal(cur->left);
        int right = traversal(cur->right);
        if(left == 2 && right == 2){
            return 0;
        }
        else if(left == 0 || right == 0){
            count++;
            return 1;
        }
        else if(left == 1 || right == 1){
            return 2;
        }
        return -1;
    }
    int minCameraCover(TreeNode* root) {
        if(traversal(root) == 0){
            count++;
        }
        return count;
    }
相关推荐
地平线开发者4 分钟前
智能驾驶感知算法的演进
算法·自动驾驶
爱丽_9 分钟前
B+ 树范围查询为什么快:页分裂/合并、索引设计与 SQL 写法优化
数据库·算法·哈希算法
WBluuue33 分钟前
Codeforces 1087 Div2(ABCDEF)
c++·算法
Yzzz-F1 小时前
2025 ICPC武汉邀请赛 G [根号分治 容斥原理+DP]
算法
abant21 小时前
leetcode 114 二叉树变链表
算法·leetcode·链表
tankeven1 小时前
HJ165 小红的优惠券
c++·算法
先积累问题,再逐次解决1 小时前
快速幂优美算法
算法
XiYang-DING2 小时前
【LeetCode】 225.用队列实现栈
算法·leetcode·职场和发展
花月C2 小时前
线性动态规划(Linear DP)
算法·动态规划·代理模式