Interval 间隔问题
2018-09-07 09:03:14
一、Merge Intervals
问题描述:
问题求解:
public List<Interval> merge(List<Interval> intervals) {
List<Interval> res = new ArrayList<>();
if (intervals.size() == 0) return res;
Collections.sort(intervals, new Comparator<Interval>() {
public int compare(Interval o1, Interval o2) {
return o1.start - o2.start;
}
});
int start = intervals.get(0).start;
int end = intervals.get(0).end;
for (int i = 1; i < intervals.size(); i++) {
if (intervals.get(i).start > end) {
res.add(new Interval(start, end));
start = intervals.get(i).start;
end = intervals.get(i).end;
}
else {
end = Math.max(end, intervals.get(i).end);
}
}
res.add(new Interval(start, end));
return res;
}
二、Insert Interval
问题描述:
问题求解:
本题的问题描述中明确的说明了,本题的给出条件中的intervals是已经排序好的,并且是没有overlapping的,因此在后续的求解过程中只需要一次遍历即可。
public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
List<Interval> res = new ArrayList<>();
int i = 0;
while (i < intervals.size() && intervals.get(i).end < newInterval.start) {
res.add(intervals.get(i++));
}
while (i < intervals.size() && intervals.get(i).start <= newInterval.end) {
newInterval.start = Math.min(newInterval.start, intervals.get(i).start);
newInterval.end = Math.max(newInterval.end, intervals.get(i).end);
i++;
}
res.add(newInterval);
while (i < intervals.size()) res.add(intervals.get(i++));
return res;
}
三、My Calendar I
问题描述:
问题求解:
解法一:Boundary Counting
对边界进行计数,最后遍历一遍即可,如果过程中有curSum大于1的情况,则表明出现了overlapping。
如果使用keySet()则会多出log(n)的时间,而本题卡时间非常紧,如果使用key进行提取,则会TLE。
如果使用entrySet(),则会Accept,但是也是将将通过。
public class MyCalendar {
TreeMap<Integer, Integer> map; public MyCalendar() {
map = new TreeMap<>();
}
public boolean book(int start, int end) {
return helper(start, end);
}
private boolean helper(int start, int end) {
map.put(start, map.getOrDefault(start, 0) + 1);
map.put(end, map.getOrDefault(end, 0) - 1);
int curSum = 0;
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
curSum += entry.getValue();
if (curSum > 1) {
map.put(start, map.get(start) - 1);
if (map.get(start) == 0) map.remove(start);
map.put(end, map.get(end) + 1);
if (map.get(end) == 0) map.remove(end);
return false;
}
}
return true;
}
}
解法二、
记录各个interval,并且所有的interval都是没有overlapping的。
public class MyCalendar {
TreeMap<Integer, Integer> treeMap; public MyCalendar() {
treeMap = new TreeMap<>();
} public boolean book(int start, int end) {
Integer floor = treeMap.floorKey(start);
if (floor != null && treeMap.get(floor) > start) return false;
Integer ceil = treeMap.ceilingKey(start);
if (ceil != null && ceil < end) return false;
treeMap.put(start, end);
return true;
}
}
四、My Calendar II
问题描述:
问题求解:
万能的Boundary Counting。
public class MyCalendarTwo {
TreeMap<Integer, Integer> map; public MyCalendarTwo() {
map = new TreeMap<>();
} public boolean book(int start, int end) {
map.put(start, map.getOrDefault(start, 0) + 1);
map.put(end, map.getOrDefault(end, 0) - 1);
int cnt = 0;
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
cnt += entry.getValue();
if (cnt > 2) {
map.put(start, map.get(start) - 1);
if (map.get(start) == 0) map.remove(start);
map.put(end, map.get(end) + 1);
if (map.get(end) == 0) map.remove(end);
return false;
}
}
return true;
}
}
五、My Calendar III
问题描述:
问题求解:
解法一:
万能的Boundary Counting。
public class MyCalendarThree {
TreeMap<Integer, Integer> map; public MyCalendarThree() {
map = new TreeMap<>();
} public int book(int start, int end) {
map.put(start, map.getOrDefault(start, 0) + 1);
map.put(end, map.getOrDefault(end, 0) - 1);
int res = 0;
int cnt = 0;
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
cnt += entry.getValue();
if (res < cnt) res = cnt;
}
return res;
}
}
解法二:
线段树求解,效率有较大的提升。
public class MyCalendarThree {
SegmentTree root;
int res; public MyCalendarThree() {
root = new SegmentTree(0, 1000000000, 0);
res = 0;
} public int book(int start, int end) {
add(start, end, root);
return res;
} private void add(int start, int end, SegmentTree root) {
if (root.m != -1) {
if (start >= root.m) add(start, end, root.right);
else if (end <= root.m) add(start, end, root.left);
else {
add(start, root.m, root.left);
add(root.m, end, root.right);
}
return;
} if (start == root.l && end == root.r) {
root.cnt++;
res = Math.max(res, root.cnt);
}
else if (start == root.l) {
root.m = end;
root.left = new SegmentTree(start, root.m, root.cnt + 1);
root.right = new SegmentTree(root.m, root.r, root.cnt);
res = Math.max(res, root.cnt + 1);
}
else if (end == root.r) {
root.m = start;
root.left = new SegmentTree(root.l, root.m, root.cnt);
root.right = new SegmentTree(root.m, root.r, root.cnt + 1);
res = Math.max(res, root.cnt + 1);
}
else {
root.m = start;
root.left = new SegmentTree(root.l, root.m, root.cnt);
root.right = new SegmentTree(root.m, root.r, root.cnt);
add(start, end, root.right);
}
}
} class SegmentTree {
int l;
int r;
int m; // m : 分割点,如果尚未分割则为-1。
int cnt;
SegmentTree left;
SegmentTree right; SegmentTree(int l, int r, int cnt) {
this.l = l;
this.r = r;
this.m = -1;
this.cnt = cnt;
this.left = null;
this.right = null;
}
}
六、Interval List Intersections
问题描述:
问题求解:
如何快速判断是否相交呢?
public int[][] intervalIntersection(int[][] A, int[][] B) {
List<int[]> res = new ArrayList<>();
int i = 0;
int j = 0;
while (i < A.length && j < B.length) {
int s = Math.max(A[i][0], B[j][0]);
int e = Math.min(A[i][1], B[j][1]);
if (s <= e) res.add(new int[]{s, e});
if (A[i][1] < B[j][1]) i++;
else j++;
}
int[][] rst = new int[res.size()][2];
for (i = 0; i < res.size(); i++) {
rst[i][0] = res.get(i)[0];
rst[i][1] = res.get(i)[1];
}
return rst;
}
Interval 间隔问题的更多相关文章
- iOS 性能调试
性能调优的方式: 1.通过专门的性能调优工具 2.通过代码优化 1. 性能调优工具: 下面针对iOS的性能调优工具进行一个介绍: 1.1 静态分析工具–Analyze 相信iOS开发者在App进行Bu ...
- Python任务调度模块 – APScheduler
APScheduler是一个Python定时任务框架,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以持久化任务.并以daemon方式运行应用.目前最新版本为3.0 ...
- Visifire Chart相关属性详解
<vc:Chart x:Name="HourlyChart" Theme="Theme1" Grid.Row="1" xmlns:vc ...
- 使用MonkeyTest对Android客户端进展压力测试
Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等),实现对正在开发的应用程序进行压力测试. 先来看一条 ...
- windows 环境和linux环境下 ping命令的区别:
Ping 是Windows自带的一个DOS命令.利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障.该命令可以加许多参数使用,键入Ping按回车即可看到详细说明.Ping 命令可 ...
- iOS-掌握了时间就掌握了一切!
Demo下载地址 一. NSDate相关知识 1.获取当前时间 [NSDate date]; 注意: 获取的当前时间是世界时间:比我们用的时间慢8个小时. 2.世界时间转化为本地时间 - (void) ...
- 数字限时增长效果实现:numberGrow.js
这是上周工作中写到的一个功能,大概的效果就是页面中有几处数字,统计公司的一些业务信息,需要在第一次出现的时候,做一个从0开始增长,大概2秒自动增长到真实数值,并停止增长的效果.这个问题的重点在于解决如 ...
- jvm指令调试
监控GC的工具分为2种:命令行工具和图形工具: 常用的命令行工具有: 注:下面的命令都在JAVA_HOME/bin中,是java自带的命令.如果您发现无法使用,请直接进入Java安装目录调用或者先设置 ...
- Python学习笔记之抽象
一.创建函数 >>> import math >>> x=1 >>> y=math.sqrt >>> callable(x) # ...
随机推荐
- 关于__declspec(dllexport)
windows下dll动态库函数的导入与导出. __declspec Microsoft Specific __declspec ( extended-attribute ) declarator l ...
- 11: python递归
1.1 递归讲解 1.定义 1. 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 2.递归特性 1. 必须有一个明确的结束条件 2. 每次进入更深一层递归时,问题 ...
- FileZilla连接腾讯云Centos7
现在需要使用ftp快速上传资料去云机备份, 于是想到FileZilla. 生成密匙文件 登录腾讯云--ssh密匙 FileZilla Client 导入密匙文件 填写登录信息 连接 另外记得开放22端 ...
- 20145212 罗天晨 《网络对抗》Exp3 Advanced 恶意代码伪装技术实践
恶意代码伪装技术实践 木马化正常软件. 啊哈--原本以为很复杂--然后我看了一下蔡野同学的博客,发现原理竟然如此简单-- 对原先生成病毒的代码稍作修改: 于是--把生成的后门软件改成骗人的名字:这里改 ...
- CentOS7的安装以及redis的下载安装和连接redis desktop manager出现的问题
因为需要在springboot下使用redis,所以打算在linux下使用redis,并且使用redis desktop manage来连接管理,但是一路上出现个种问题现在总结一下. 如何安装Cent ...
- 树之105 Construct Binary Tree from Preorder and Inorder Traversal
题目链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ 参考链 ...
- Spring 学习——Spring IOC概念
Spring IOC 接口及面向接口编程 接口 定义及理解:接口是一个类的抽象声明,用于由内部操作分离出外部沟通的方式,使其内部进行修改而不影响其外部连接沟通的一种交互方式.不对外公开逻辑处理,只是返 ...
- ODAC(V9.5.15) 学习笔记(十一)TOraEncryptor、TOraPackage和TOraAlerter
TOraEncryptor 名称 类型 说明 DataHeader TCREncDataHeader 一些附加信息放入加密数据中,包括: ehNone 无附加信息 ehTag GUID和随机生成的 ...
- route 工具
route工具 route工具主要用来查看或修改内核路由表 查看内核路由表 route [-nee] 参数说明: -n:不要使用协议或主机名称,直接使用 IP 或 port number:-ee:使用 ...
- 配置vim
VundleVuldle是一个全自动的插件管理器,让我们通过维护插件列表的方式管理插件.它为安装.更新.删除插件提供了方便的命令.在安装Git的情况下(本文不赘述Git的安装),输入命令: git c ...