代码随想录算法训练营第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

相关推荐
带多刺的玫瑰36 分钟前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔38 分钟前
《线性代数的本质》
线性代数·算法·决策树
yigan_Eins1 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
阿史大杯茶1 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
დ旧言~2 小时前
【高阶数据结构】图论
算法·深度优先·广度优先·宽度优先·推荐算法
张彦峰ZYF2 小时前
投资策略规划最优决策分析
分布式·算法·金融
The_Ticker2 小时前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
爪哇学长2 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
Dola_Pan3 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi3 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse