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

第八章 贪心算法 part05

56. 合并区间

本题也是重叠区间问题,如果昨天三道都吸收的话,本题就容易理解了。

复制代码
/**
时间复杂度 : O(NlogN) 排序需要O(NlogN)
空间复杂度 : O(logN)  java 的内置排序是快速排序 需要 O(logN)空间

*/
class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> res = new LinkedList<>();
        //按照左边界排序
        Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));
        //initial start 是最小左边界
        int start = intervals[0][0];
        int rightmostRightBound = intervals[0][1];
        for (int i = 1; i < intervals.length; i++) {
            //如果左边界大于最大右边界
            if (intervals[i][0] > rightmostRightBound) {
                //加入区间 并且更新start
                res.add(new int[]{start, rightmostRightBound});
                start = intervals[i][0];
                rightmostRightBound = intervals[i][1];
            } else {
                //更新最大右边界
                rightmostRightBound = Math.max(rightmostRightBound, intervals[i][1]);
            }
        }
        res.add(new int[]{start, rightmostRightBound});
        return res.toArray(new int[res.size()][]);
    }
}

738.单调递增的数字

复制代码
class Solution {
    public int monotoneIncreasingDigits(int N) {
        String[] strings = (N + "").split("");
        int start = strings.length;
        for (int i = strings.length - 1; i > 0; i--) {
            if (Integer.parseInt(strings[i]) < Integer.parseInt(strings[i - 1])) {
                strings[i - 1] = (Integer.parseInt(strings[i - 1]) - 1) + "";
                start = i;
            }
        }
        for (int i = start; i < strings.length; i++) {
            strings[i] = "9";
        }
        return Integer.parseInt(String.join("",strings));
    }
}

java版本1中创建了String数组,多次使用Integer.parseInt了方法,这导致不管是耗时还是空间占用都非常高,用时12ms,下面提供一个版本在char数组上原地修改,用时1ms的版本

968.监控二叉树 (可跳过)

本题是贪心和二叉树的一个结合,比较难,一刷大家就跳过吧。

复制代码
class Solution {
    static int ans;
    public int minCameraCover(TreeNode root) {
        ans = 0; // 初始化
        if(f(root) == 0) ans ++;
        return ans;
    }
    // 定义 f 函数有三种返回值情况
    // 0:表示 x 节点没有被相机监控,只能依靠父节点放相机
    // 1:表示 x 节点被相机监控,但相机不是放在自身节点上
    // 2:表示 x 节点被相机监控,但相机放在自身节点上
    public static int f(TreeNode x) {
        if(x == null) return 1; // 空树认为被监控,但没有相机
        // 左右递归到最深处
        int l = f(x.left);
        int r = f(x.right);
        // 有任意一个子节点为空,就需要当前节点放相机,不然以后没机会
        if(l == 0 || r == 0) {
            ans ++; // 放相机
            return 2;
        }
        // 贪心策略,左右子树都被监控,且没有监控到当前节点,
        // 那么最有利的情况就是将相机放置在当前节点父节点上,
        // 因为这样能多监控可能的子树节点和父父节点
        if(l == 1 && r == 1) return 0;
        // 剩下情况就是左右子树有可能为 2,即当前节点被监控
        return 1; 
    }
}

总结

可以看看贪心算法的总结,贪心本来就没啥规律,能写出个总结篇真的不容易了。

https://programmercarl.com/贪心算法总结篇.html

相关推荐
迈巴赫车主25 分钟前
蓝桥杯19724食堂
java·数据结构·算法·职场和发展·蓝桥杯
6Hzlia43 分钟前
【Hot 100 刷题计划】 LeetCode 78. 子集 | C++ 回溯算法题解
c++·算法·leetcode
Kethy__1 小时前
计算机中级-数据库系统工程师-数据结构-查找算法
数据结构·算法·软考·查找算法·计算机中级
所以遗憾是什么呢?1 小时前
【题解】Codeforces Round 1081 (Div. 2)
数据结构·c++·算法·acm·icpc·ccpc·xcpc
xiaoye-duck2 小时前
《算法题讲解指南:递归,搜索与回溯算法--综合练习》--14.找出所有子集的异或总和再求和,15.全排列Ⅱ,16.电话号码的字母组合,17.括号生成
c++·算法·深度优先·回溯
OOJO2 小时前
c++---vector介绍
c语言·开发语言·数据结构·c++·算法·vim·visual studio
汀、人工智能2 小时前
05 - 函数基础
数据结构·算法·数据库架构·05 - 函数基础
HAPPY酷2 小时前
Python高级架构师之路——从原理到实战
java·python·算法
枫叶林FYL2 小时前
第9章 因果推理与物理理解
人工智能·算法·机器学习
小白zlm3 小时前
预畸变双线性变换
单片机·嵌入式硬件·算法·电机控制