算法练习:重叠区间个数

一、题目描述

给定多个可能重叠的区间,找出重叠区间的个数。

举例如下:

输入:[1,5],[10,15],[5,10],[20,30]

输出:2

说明:题意应该是找出重叠区间中区间的最大个数,当没有区间重叠时,重叠个数最大为1,比如

输入为:[1,5],[10,15],则输出为1;

输入为:[1,2],[2,3],[3,4],[4,5],则输出为2(重叠区间相互之间都要有交集);

输入为:[1,7],[2,5],[3,4],[8,15],[9,17],[20,25],则输出为3。

二、题目分析

此题解题方法比较简单,只要将区间分隔成各个点,每个点有两个属性,一个是值,一个是标志(0起点,1止点),然后对这些点排序,最后,从头开始扫描排序的结果,遇到起点重叠个数加1,遇到止点重叠个数减1,并且记录好重叠个数的最大值。

本算法的时间复杂度为O(nlogn),因为算法时间主要消耗在排序上。

三、算法实现

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <Windows.h>
using namespace std;

//区间定义
class Interval
{
public:
	Interval( int iStart, int iEnd)
		:m_iStart( iStart), m_iEnd(iEnd){}
	int m_iStart;
	int m_iEnd;
};

typedef vector<Interval> IntervalVec;

//区间拆分的点定义
class PointComparable
{
public:
	PointComparable( int iVal, int iType )
		:m_iVal( iVal ), m_iType( iType ){}

	//重载小于操作符,排序使用
	bool operator < ( const PointComparable& pcPoint )
	{
		if ( this->m_iVal == pcPoint.m_iVal )
		{
			return this->m_iType < pcPoint.m_iType;
		}
		return this->m_iVal < pcPoint.m_iVal;
	}

	int m_iVal;
	int m_iType;//点类型,0为起点,1为终点
};

int GetOverlappedIntervalMaxCount( const IntervalVec& intvVec )
{
	vector<PointComparable> pcVec;
	for ( IntervalVec::const_iterator it = intvVec.begin();
		it != intvVec.end(); ++it )
	{
		pcVec.push_back( PointComparable( it->m_iStart, 0 ) );
		pcVec.push_back( PointComparable( it->m_iEnd, 1 ) );
	}

	sort( pcVec.begin(), pcVec.end() );

	int iMaxCount = 0;
	int iCurCount = 0;
	for ( vector<PointComparable>::iterator itTemp = pcVec.begin();
		itTemp != pcVec.end(); ++itTemp )
	{
		cout << itTemp->m_iVal << " " << itTemp->m_iType << endl;
		if ( itTemp->m_iType == 0 )
		{
			iCurCount++;
			iMaxCount = __max( iCurCount, iMaxCount );
		}
		else
		{
			iCurCount--;
		}
	}

	return iMaxCount;
}

int main()
{
	IntervalVec intvVec;
// 	intvVec.push_back( Interval(1,5) );
// 	intvVec.push_back( Interval(5,10) );

// 	intvVec.push_back( Interval(1,7) );
// 	intvVec.push_back( Interval(2,5) );
// 	intvVec.push_back( Interval(3,6) );
// 	intvVec.push_back( Interval(8,15) );
// 	intvVec.push_back( Interval(9,17) );
// 	intvVec.push_back( Interval(20,25) );

	intvVec.push_back( Interval(1,2) );
	intvVec.push_back( Interval(2,3) );
	intvVec.push_back( Interval(3,4) );
	intvVec.push_back( Interval(4,5) );

	cout << "最大重叠区间个数:" << GetOverlappedIntervalMaxCount( intvVec )  
<span style="white-space:pre">	</span>cout << endl;
	return 0;
}

系列文章说明:

1.本系列文章[算法练习],仅仅是本人学习过程的一个记录以及自我激励,没有什么说教的意思。如果能给读者带来些许知识及感悟,那是我的荣幸。

2.本系列文章是本人学习陈东锋老师《进军硅谷,程序员面试揭秘》一书而写的一些心得体会,文章大多数观点均来自此书,特此说明!

3.文章之中,难免有诸多的错误与不足,欢迎读者批评指正,谢谢.

作者:山丘儿

转载请标明出处,谢谢。原文地址:http://blog.csdn.net/s634772208/article/details/46492651

时间: 2024-10-08 09:06:59

算法练习:重叠区间个数的相关文章

求重叠区间个数,某书某题错例分析

大意就是我淘钱买了一本题集,觉得书中有些地方作者太随意,例子错得不严谨,一度阻碍阅读.作为消费者不得不拿出来说一说.本文本着不迷信,实事求是精神.本文编排如下:1.引用书中原例2.主观分析例子有错3.代码运行验证其错4.修正例子代码5.另一个求值代码现在开始. 下面是书中原例引用: 求重叠区间个数 给定多个可能重叠的区间,找出重叠区间的个数.区间定义如下: class Interval { int start; // 起点 int end; // 止点 Interval(int a, intb)

最大不重叠区间

http://zju.acmclub.com/index.php? app=problem_title&id=1&problem_id=1126 RT,给定n个区间.每一个区间有開始时间si和结束时间ei, 问在数轴上怎样摆放能使在没有重叠区间的情况下区间数目达到最大? 分析:典型的贪心思路.在<算法导论>贪心那一章的第一个样例即是它--活动选择问题 解法:按区间的结束时间从小到大排序后.从小的区间按顺序选取: (1)假设当前区间与已经覆盖的位置重叠(与当前最右位置进行比較).

HDU 4343 多查询求区间内的最大不相交区间个数-思维&amp;贪心-卡时间&amp;二分&amp;剪枝

题意:给你一些区间,现在有m个查询,求出每个查询的区间内的最大的不相交区间个数 分析: 几天前那道说谎问题时用dp的摞箱子模型求的最大的不相交区间个数,但是这题不能用这个方法,因为这题是动态的查询,不可能每个查询dp一次,超时. 这题用贪心策略.求区间[l~r]里的最大不相交区间,贪心策略就应该先选该区间内右端点最小的,这样给以后待选的区间留下更大的空间,所以我们的做法就是先按照区间的右端点排序,然后每次查询依次挑出查询区间里右端点最小的,并且把查询区间的左端点更新为刚才挑出的区间的右端点(这个

编程算法 - 最小的k个数 代码(C)

最小的k个数 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入n个整数, 找出其中的最小k个数. 使用快速排序(Quick Sort)的方法求解, 把索引值(index)指向前k个数. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio.h> #include <stdl

编程算法 - 最小的k个数 红黑树 代码(C++)

最小的k个数 红黑树 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入n个整数, 找出其中的最小k个数. 使用红黑树(multiset), 每次替换最大的值, 依次迭代. 时间复杂度: O(nlogk). 代码: /* * main.cpp * * Created on: 2014年6月29日 * Author: wang */ #include <iostream> #include <vector> #includ

1110: 零起点学算法17——比较2个数大小

1110: 零起点学算法17--比较2个数大小 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 3272  Accepted: 1639[Submit][Status][Web Board] Description 输入2个整数,按照从大到小输出 Input 2个整数n和m(多组测试数据) Output 按照从大到小输出,中间用空格隔开(每组测试数据一行) Sample Input 14 32 2

算法5-7:区间搜索

区间搜索问题就是给定一系列区间,和一个待测区间,求与待测区间相交的区间. 为了解决这个问题,需要专门编写一个类,这个类的接口如下: public interface IntervalST<Key extends Comparable<Key>, Value> { void put(Key lo, Key hi, Value value); Value get(Key lo, Key hi) void delete(Key lo, Key hi) Iterable<Value&

小算法:求一个数的乘方 - 使用递归

1 /** 2 * 求一个整数的乘方 3 * @param num 要乘方的数字 4 * @param power 多少次方 5 * @return 6 */ 7 public static int power(int num,int power){ 8 if(power == 1){ 9 return num; 10 } 11 if(power % 2 == 0){ 12 return power(num, power / 2) * power(num, power / 2); 13 }els

剪花布条 HDU - 2087(kmp,求不重叠匹配个数)

Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样.花纹条和小饰条不会超过1000个字符长.如果遇见#字符,则不再进行工作. Output 输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出