lintcode 1063 · 我的日历III 【hard 线段树】

题目链接,描述

https://www.lintcode.com/problem/1063

java 复制代码
实现一个MyCalendarThree 来储存你的时间。一个新的事件 总是 可以被加入。

你的类会有一种方法:book(int start, int end)。 正式的说,这代表在一个半开区间 [start, end) 上进行预订,实数x 的范围即 start <= x < end。

当K个事件有一个非空交集的时候,一个K预订将会发生。(即,某一个时刻对于K个事件是共用的)

对于每一个对于方法 MyCalendar.book的调用,返回一个整数K,代表日历中存在K预订的最大的整数。

你的类将会这样被调用: MyCalendarThree cal = new MyCalendarThree(); MyCalendarThree.book(start, end)。

每个测试用例将会调用 MyCalendarThree.book 至多400次 。
在调用MyCalendarThree.book(start, end)时, start 和 end是在[0, 10^9]内的整数。
样例
样例1

输入:
MyCalendarThree()
book(10,20)
book(50,60)
book(10,40)
book(5,15)
book(5,10)
book(25,55)

输出: [1,1,2,3,3,3]
说明:
前两个可以被预订的事件是不相交的,所以说最大的K预订是1预订。
第三个事件[10,  40)和第一个事件相交,最大的K预订是2预订。
剩下的事件导致最大的K预订只是3预订。
注意到最后一个事件在本地导致2预订,但是答案依然是3预订
因为比如, [10, 20), [10, 40), and [5, 15)依然是三重预订。
样例2

输入:
MyCalendarThree()
book(1,2)
book(1,2)
book(2,3)

输出: [1,2,2]

思路

前置知识:线段树

参考代码

java 复制代码
class MyCalendarThree {
 SegmentNode root; //线段树根节点

        public MyCalendarThree() {
            root = build(0,100000);
        }

        public int book(int start, int end) {
            for (int i = start; i < end; i++) {
                update(root, i, 1);
            }
            return root.max;
        }

        static class SegmentNode { //线段树节点定义
            int start, end, max;
            SegmentNode left, right;

            public SegmentNode(int s, int e) {
                start = s;
                end = e;
            }
        }

        //根据开始,结束标志,创建线段树
        public static SegmentNode build(int start, int end) {
            if (start > end) return null;
            if (start == end)
                return new SegmentNode(start, end);

            SegmentNode root = new SegmentNode(start, end);

            int mid = start + (end - start) / 2;
            root.left = build(start, mid);
            root.right = build(mid + 1, end);
            return root;
        }


        //更新线段树
        public static void update(SegmentNode root, int index, int val) {
            if (root.start == root.end && root.start == index) {
                root.max += val;
                return;
            }

            int mid = (root.start + root.end) / 2;
            if (index <= mid && index >= root.start) {
                update(root.left, index, val);
            }

            if (index > mid && index <= root.end) {
                update(root.right, index, val);
            }


            root.max = Math.max(root.left.max, root.right.max);
        }
}

/**
 * Your MyCalendarThree object will be instantiated and called as such:
 * MyCalendarThree obj = new MyCalendarThree();
 * int param_1 = obj.book(start,end);
 */
相关推荐
UIU1145 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
论文复现现场5 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi5 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
秋天的怀念_David6 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
碧海银沙音频科技研究院7 小时前
在PC电脑上用Whisper→Marian算法实现离线语音翻译功能
算法·whisper
niyongsheng7 小时前
3D 装箱算法工程化:数据结构、放置启发式与支撑规则
数据结构·算法·rust
叉烧滑蛋9 小时前
B站台湾大学郭彦甫|MATLAB 学习笔记|04 变量与档案存取
数据结构
j7~10 小时前
【穷举、深搜与回溯算法】一棵决策树讲透全排列与子集
数据结构·c++·算法·leetcode·回溯·递归
傅科摆 _ py11 小时前
DP,贪心,堆和栈,二分力扣复习
开发语言·python·算法
Shaoshing11 小时前
LeetCode100 42.接雨水
java·算法·leetcode