• Java实现 LeetCode 732 我的日程安排表 III(暴力 || 二叉树)


    732. 我的日程安排表 III

    实现一个 MyCalendar 类来存放你的日程安排,你可以一直添加新的日程安排。

    MyCalendar 有一个 book(int start, int end)方法。它意味着在start到end时间内增加一个日程安排,注意,这里的时间是半开区间,即 [start, end), 实数 x 的范围为, start <= x < end。

    当 K 个日程安排有一些时间上的交叉时(例如K个日程安排都在同一时间内),就会产生 K 次预订。

    每次调用 MyCalendar.book方法时,返回一个整数 K ,表示最大的 K 次预订。

    请按照以下步骤调用MyCalendar 类: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)

    示例 1:

    MyCalendarThree();
    MyCalendarThree.book(10, 20); // returns 1
    MyCalendarThree.book(50, 60); // returns 1
    MyCalendarThree.book(10, 40); // returns 2
    MyCalendarThree.book(5, 15); // returns 3
    MyCalendarThree.book(5, 10); // returns 3
    MyCalendarThree.book(25, 55); // returns 3
    解释: 
    前两个日程安排可以预订并且不相交,所以最大的K次预订是1。
    第三个日程安排[10,40]与第一个日程安排相交,最高的K次预订为2。
    其余的日程安排的最高K次预订仅为3。
    请注意,最后一次日程安排可能会导致局部最高K次预订为2,但答案仍然是3,原因是从开始到最后,时间[10,20][10,40][5,15]仍然会导致3次预订。
    

    说明:

    每个测试用例,调用 MyCalendar.book 函数最多不超过 400次。
    调用函数 MyCalendar.book(start, end)时, start 和 end 的取值范围为 [0, 10^9]。
    PS:
    暴力

    class MyCalendarThree {
    
         private TreeMap<Integer, Integer> calendar;
    
        public MyCalendarThree() {
            calendar = new TreeMap<>();
        }
    
        public int book(int start, int end) {
    
            // 添加至日程中
            calendar.put(start, calendar.getOrDefault(start, 0) + 1);
            calendar.put(end, calendar.getOrDefault(end, 0) - 1);
    
            // 记录最大活跃的日程数
            int max = 0;
            // 记录活跃的日程数
            int active = 0;
    
            for (Integer d : calendar.values()) {
                // 以时间线统计日程
                active += d;
    
                // 找到活跃事件数量最多的时刻,记录下来。
                if (active > max) {
                    max = active;
                }
            }
    
            return max;
        }
    }
    
    /**
     * Your MyCalendarThree object will be instantiated and called as such:
     * MyCalendarThree obj = new MyCalendarThree();
     * int param_1 = obj.book(start,end);
     */
    

    PS:
    二叉树

    class MyCalendarThree {
     public static class SegmentTree {
            public static class Node {
    
                private int  lo;
                private int  hi;
                private int  range;
                private int  maxCover = 0;
                private int  lazy     = 0;
                private Node left;
                private Node right;
    
                public Node(int lo, int hi) {
                    this.lo = lo;
                    this.hi = hi;
                    this.range = hi - lo;
                }
            }
    
            Node root = null;
    
            public int addRange(int qLo, int qHi) {
                checkRoot(qLo, qHi);
                update(root, qLo, qHi, 1);
                return root.maxCover;
            }
    
            private void update(Node root, int qLo, int qHi, int diff) {
                if (root == null) {
                    return;
                }
                checkLazy(root);
                if (qHi <= root.lo || root.hi <= qLo) {
                    return;
                }
                checkChildren(root);
                if (qLo <= root.lo && root.hi <= qHi) {
                    root.maxCover += diff;
                    if (root.left != null) {
                        root.left.lazy += diff;
                    }
                    if (root.right != null) {
                        root.right.lazy += diff;
                    }
                    return;
                }
                update(root.left, qLo, qHi, diff);
                update(root.right, qLo, qHi, diff);
                root.maxCover = Math.max(root.left.maxCover, root.right.maxCover);
            }
    
            private void checkChildren(Node root) {
                if (root.range <= 1) {
                    return;
                }
                if (root.left != null && root.right != null) {
                    return;
                }
                int mid = root.lo + (root.hi - root.lo) / 2;
                if (root.left == null) {
                    int r = root.right == null ? mid : root.right.lo;
                    root.left = new Node(root.lo, r);
                }
                if (root.right == null) {
                    root.right = new Node(root.left.hi, root.hi);
                }
            }
    
            private void checkLazy(Node root) {
                if (root.lazy == 0) {
                    return;
                }
                root.maxCover += root.lazy;
                checkChildren(root);
                //propagation
                if (root.left != null) {
                    root.left.lazy += root.lazy;
                    root.right.lazy += root.lazy;
                }
                //reset lazy
                root.lazy = 0;
            }
    
            private void checkRoot(int qLo, int qHi) {
                if (root == null) {
                    root = new Node(qLo, qHi);
                    return;
                }
                while (qHi > root.hi) {
                    Node newR = new Node(root.lo, Math.min(1000000000, root.hi + root.range));
                    newR.left = root;
                    newR.maxCover=root.maxCover;
                    root = newR;
                }
                while (qLo < root.lo) {
                    Node newR = new Node(Math.max(0, root.lo - root.range), root.hi);
                    newR.right = root;
                    newR.maxCover=root.maxCover;
                    root = newR;
                }
            }
        }
    
        SegmentTree st = new SegmentTree();
    
        public MyCalendarThree() {
        }
    
        public int book(int start, int end) {
            return st.addRange(start, end);
        }
    
    }
    
    /**
     * Your MyCalendarThree object will be instantiated and called as such:
     * MyCalendarThree obj = new MyCalendarThree();
     * int param_1 = obj.book(start,end);
     */
    
  • 相关阅读:
    TMD 这个写笔记的号,盗了有意思吗
    类成员的指针必须NULL化,否则是乱七八糟的东西
    超前引用不可使用类名来定义变量和函数的变量参数,只可用来定义引用或者指针。
    XP下,移动窗口产生重影的问题
    生成ico格式图标
    设置窗口的z-order总是在最底部
    关于windows的锁定状态
    使用Layered Window遇到的一些问题及解决方法
    转-使用wifi调试程序
    URL的格式
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12946240.html
Copyright © 2020-2023  润新知