每天一到算法题--重叠区间大小
来源:互联网 发布:python 调用c dll 编辑:程序博客网 时间:2024/05/17 23:52
题目描述
请编写程序,找出下面 “ 输入数据及格式 ” 中所描述的输入数据文件中最大重叠区间的大小。
对一个正整数 n ,如果 n 在数据文件中某行的两个正整数(假设为 A 和 B )之间,即 A<=n<=B 或 A>=n>=B ,则 n 属于该行;如果 n 同时属于行 i 和 j ,则 i 和 j 有重叠区间;重叠区间的大小是同时属于行 i 和 j 的整数个数。
例如,行(10 20 )和( 12 25 )的重叠区间为 [12 20] ,其大小为 9 ;行( 20 10 )和( 12 18 )的重叠区间为 [10 12] ,其大小为 3 ;行 (20 10) 和( 20 30 )的重叠区间大小为 1 。
输入数据:程序读入已被命名为 input.txt 的输入数据文本文件,该文件的行数在 1 到 1,000,000 之间,每行有用一个空格分隔的 2 个正整数,这 2 个正整数的大小次序随机,每个数都在 1 和 2^32-1 之间。(为便于调试,您可下载测试 input.txt 文件,实际运行时我们会使用不同内容的输入文件。)
输出数据:在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出 0 。
评分标准:程序输出结果必须正确,内存使用必须不超过 256MB ,程序的执行时间越快越好。
算法思路:
采用递推的方式。
先对所有区间以起始端点为基础进行排序,得到一个排序后的区间序列。然后对每一个区间考察后面可能与其重叠的区间。
具体方式为:
设当前的区间为c[a, b], 紧邻的下一个区间为n[a,b].
- 当 c.b < n.a时, n,c没有重叠区间。又由于区间是按照起始点递增排序,所以后续的区间也不会与c有重叠区间。
- 当 c.b >= n.a 时候,n, c有重叠区间。大小为 min{c.b-n.a, n.b-n.a}
- 将得到的当前覆盖长度与保存的max做比较,保存大者。
- 如此对所有的区间都进行这个操作。值得注意的是,当 c.b > n.b时候,n区间被包含在c区间中。在后续的遍历中就无需考虑n这个区间了。小小的技巧在特殊情况下(比如很多区间嵌套),会很快提高运行速度。
代码:
#include <iostream>#include <fstream>#include <algorithm>#include <vector>using namespace std;// find the longest overlap intervalclass Interval { public : int first; int last; public: Interval(int first, int last);};Interval::Interval(int first, int last){ this->first = first; this->last = last;}bool intervalCompare(Interval a, Interval b){ return a.first < b.first;}void swap(int & a, int & b){ int temp; temp = a; a = b; b = temp;}int max(int a, int b){ return a > b? a : b;}int min(int a, int b){ return a < b? a : b;}void print(vector<Interval> * v){ vector<Interval>::iterator it; for (it=v->begin(); it!=v->end(); ++it) cout << "[" << it->first << "," << it->last<<"]\t"; cout << endl; }int main(){ ifstream in("c:/input.txt"); vector<Interval> * allIntervals = new vector<Interval>(); vector<Interval>::iterator it; int first; int last; while(in >> first >> last) { if(first > last) swap(first, last); Interval *a = new Interval(first, last); allIntervals->push_back(*a); } cout << "input is : " << endl; print(allIntervals); sort(allIntervals->begin(), allIntervals->end(), intervalCompare); cout << "after sorted, is : " << endl; print(allIntervals); //find the longest overlap //µ±Ç°µÄinterval c[a,b],½ô½ÓÆäºóµÄinterva n[a,b] //µ± c.b < n.a ʱ£¬Çø¼äûÓи²¸Ç //µ± c.b >= n.a ʱ£¬µ±Ç°µÄÇø¼ä¸²¸ÇΪ max(c.b-n.a, n.b-n.a). int maxOverlapLength = 0; int length = allIntervals->size(); for(int i = 0; i < length-1; i++) { Interval cur = (*allIntervals)[i]; int j = i+1; Interval next = (*allIntervals)[j]; while(cur.last >= next.first) { int m = min(cur.last-next.first, next.last-next.first); maxOverlapLength = max(m, maxOverlapLength); j = j+1; next = (*allIntervals)[j]; if(cur.last >= next.last) { i++; } } } cout << "max overlap length is : " << maxOverlapLength << endl; system("pause"); return 0;}
讨论:
这里采用的方式是将所有数据读入内存,此时,很有可能会有内存益处的情况。此时可以先遍历一边,将区间分成两部分/四部分,每一部分按照上面的方法给出最大重叠区间。然后在考虑跨越两个部分的边界情况。综合得到结果。
- 每天一到算法题--重叠区间大小
- 重叠区间大小
- 最大重叠区间大小
- 区间重叠判断算法
- 区间重叠判断算法
- 求最大重叠区间大小
- 算法练习:重叠区间个数
- 重叠区间个数(算法)
- 区间树上的重叠区间查找算法
- 区间树上的重叠区间查找算法
- 157 求最大重叠区间大小
- (算法)判断两个区间是否重叠
- 【算法】求两个区间的重叠长度
- 区间树中区间重叠检测算法正确性的证明
- 面试题精选(69):求最大重叠区间大小
- 区间重叠
- 每天一算法
- 【数字题3】最大重叠子区间
- 磁盘分区的删除
- JSP内置对象(2)----out、application
- 在Eclipse下搭建Android开发环境教程
- 第七周作业任务一
- 2.创建基本应用程序模板
- 每天一到算法题--重叠区间大小
- Android SDK安装失败的解决方法
- C++多核高级编程 - 01 新的计算机体系结构及多核设计
- 第七周 任务1
- 第七周任务(1)
- 信息资源管理
- 随笔
- 素数打表
- 注册表命令大全