Java中的平衡树
给定一堆线段,每个线段都有一个起点、一个终点,用数组[(beg1,end1),(beg2,end2),(beg3,end3)......]来表示。可以提出以下问题:
- 这些线段是否有重合部分
- 这些线段的总长度是多少(多条线段重合部分只计算一次),这个问题相当于上面那个问题的加强版
如果一次性给定了这些线段,只需对这些线段进行排序即可O(nlog(n)),然后从左往右O(n)复杂度扫描一遍。
这道题要求在线算法。所以就需要对每条线段的start进行排序,当插入时,判断start的上界线段、下界线段是否可以容纳当前线段即可。如果用数组实现,每次插入需要O(n/2)的复杂度。如果用平衡树,每次插入需要O(log(n))的复杂度。
这种方法复杂度为O(Nlog(N))
import java.util.TreeMap;
class MyCalendar {
class Node {
int start;
int end;
Node(int start, int end) {
this.start = start;
this.end = end;
}
}
TreeMap<Integer, Node> a = new TreeMap<>();
public MyCalendar() {
a.put(-1, new Node(-1, 0));
a.put((int) (1e9 + 7), new Node((int) (1e9 + 7), (int) (1e9 + 8)));
}
public boolean book(int start, int end) {
Node floor = a.floorEntry(start).getValue();
Node ceil = a.ceilingEntry(start).getValue();
if (start >= floor.end && end <= ceil.start) {
a.put(start, new Node(start, end));
return true;
} else {
return false;
}
}
}
此题还有另一种方法
对于N条线段,每条线段左端点为+1,右端点为-1,从左往右扫描,初始时s=0,遇到左端点s就+1,遇到右端点s就-1,在这个过程中,s的值必然始终为0或者1。
这种方法复杂度为O(N*N),其中N为线段的个数。
这种方法很容易扩展到允许线段交叉2次的情况,只需要改一下从左往右扫描时允许的最大上界即可。题目链接。
class MyCalendar{
public:
map<int, int> delta;
bool book(int start, int end) {
delta[start]++;
delta[end]--;
int booked = 0;
for (auto &d : delta) {
booked += d.second;
if (booked ==2) {
delta[start]--;
delta[end]++;
return false;
}
}
return true;
}
};
最后补充一个小技巧:一维数轴上,如何判断两条线段相交?
问题可以转化为:一位数轴上,如何求两条线段公共部分的长度?
记线段1(a0,a1),线段2(b0,b1)
答案是:min(a1,b1)-max(a0,b0)
于是两条线段相交的充要条件是:min(a1,b1)>max(a0,b0)
Java中的平衡树的更多相关文章
- java中的锁
java中有哪些锁 这个问题在我看了一遍<java并发编程>后尽然无法回答,说明自己对于锁的概念了解的不够.于是再次翻看了一下书里的内容,突然有点打开脑门的感觉.看来确实是要学习的最好方式 ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- Java中的Socket的用法
Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...
- java中Action层、Service层和Dao层的功能区分
Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...
- Java中常用集合操作
一.Map 名值对存储的. 常用派生类HashMap类 添加: put(key,value)往集合里添加数据 删除: clear()删除所有 remove(key)清除单个,根据k来找 获取: siz ...
- java中的移位运算符:<<,>>,>>>总结
java中有三种移位运算符 << : 左移运算符,num << 1,相当于num乘以2 >> : 右移运算符,num >& ...
- 关于Java中进程和线程的详解
一.进程:是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命 周期.它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而 ...
- Java中的进程和线程
Java中的进程与线程 一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是 ...
- Java中的进程与线程(总结篇)
详细文档: Java中的进程与线程.rar 474KB 1/7/2017 6:21:15 PM 概述: 几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进 ...
随机推荐
- python里的引用、浅拷贝、深拷贝
参考: 1.http://wsfdl.com/python/2013/08/16/%E7%90%86%E8%A7%A3Python%E7%9A%84%E6%B7%B1%E6%8B%B7%E8%B4%9 ...
- 【BZOJ】【3668】【NOI2014】起床困难综合症
贪心 位运算的题……基本都是按位来做的?... 从高位到低位,贪心来搞就可以了…… 这都算不上是数位DP吧= = /****************************************** ...
- JDBC操作数据库的批处理
在JDBC开发中,操作数据库需要与数据库建立连接,然后将要执行的SQL语句传送到数据库服务器,最后关闭数据库连接,都是按照这样一个流程进行操作的.如果按照该流程执行多条SQL语句,那么就需要建立多个数 ...
- 不错网络性能相关的文章-BaiduRPC
http://wiki.baidu.com/display/RPC/Threading+Overview#ThreadingOverview-单线程reactor Threading Overview ...
- 第一章 第一个spring boot程序
环境: jdk:1.8.0_73 maven:3.3.9 spring-boot:1.2.5.RELEASE(在pom.xml中指定了) 注意:关于spring-boot的支持, 最少使用jdk7(j ...
- Android下拉刷新-SwipeRefreshLayout
现在市面上新闻类的App基本上都有下拉刷新,算是一个标配吧,网上关于下拉刷新的博客也有很多,实现方式可以使用开源的PullToRefresh,自定义ListView,或者可以直接使用LineLayOu ...
- 一个常见下拉菜单的样式:一体化小三角(纯css手写解决)
类似下拉菜单2个一体化小三角,习惯上用字体图标加jQuery处理,比较方便,但是下面纯css手写解决方式,效果也还不错,对CSS知识也是一个比较好的孔固. 小三角用了2种不同处理方式:1.利用bord ...
- Oracle根据字段值找到表名和列名
方法1: --Oracle 根据字段值查询其所在的表.字段 DECLARE CURSOR cur_query IS SELECT table_name, column_name, data_type ...
- Install Identity management Database
Install Identity management Database Installing Oracle Fusion Applications > Setting up I ...
- jquery ui autocomplete 模拟百度搜索自动提示
直接上代码 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=" ...