重叠区间的个数

本文介绍了一种计算多个可能重叠区间中最大重叠数量的算法。通过将区间拆分为起点和终点并进行排序,可以高效地找到重叠部分。代码示例使用了Java实现。

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

题解:

我们首先根据区间点的不同类型进行分类,分成start和end点。然后我们根据这些start和end节点的大小来排序,可以用Comparator接口,重写其compareTo方法。然后将按照Start排序之后的节点对,然后从前往后走,依次根据后一个节点对的起始节点的值和前一个节点的结束节点的值比较,如果后一个比前一个小,那么就说明存在重合区间,需要累加。

代码如下:

class Interval
{
    int start;
    int end;
    Interval(int a,int b)
    {
        start = a;
        end = b;
    }
}


class Com implements Comparator<Interval>
{
    public int compare(Interval i1,Interval i2)   //这个方法是看这个Interval类中的start值
    {
        if(i1.start == i2.start)
            return 0;
        else if(i1.start > i2.start)   //如果前面那一个大于后面那一个,那么就要交换
            return 1;
        else
            return -1;
    }
}

public class getOverlappingCount
{
    public static int GetOverLappingCount(Interval[] A)
    {
        int max = 0,count = 1;    
        if(A == null || A.length == 0)
            return max;
        ArrayList<Interval> list = new ArrayList<Interval>();
        for(int i = 0; i < A.length; i++)
        {
            list.add(new Interval(A[i].start,A[i].end));
            //list.add(new Interval(A[i].end,A[i].end));
        }
        Collections.sort(list,new Com());
        /*for(int k = 0; k < list.size(); k++)
            System.out.println(list.get(k).start + "  " + list.get(k).end);*/
        for(int i = 0; i < list.size() - 1; i++)
        {
                if(list.get(i+1).start <= list.get(i).end)
                    count++;
                else
                {
                    if(count != 1)
                    {
                        max = max > count ? max : count;
                        count = 1;
                    }
                }
                max = max > count ? max : count;
                //System.out.println(count + " " + max);
        }
        return max;
    }
    /*public static void main(String[] args)   //测试样例
    {
        Interval i = new Interval(1,5);
        Interval j = new Interval(10,15);
        Interval k = new Interval(6,10);
        Interval l = new Interval(20,30);
        Interval m = new Interval(30,40);
        Interval n = new Interval(35,40);
        Interval[] in = new Interval[2];
        in[0] = i;
        in[1] = j;
        in[2] = k;
        in[3] = l;
        in[4] = m;
        in[5] = n;
        System.out.println(GetOverLappingCount(in));
    }*/
}
这以下的代码有误,采用的思路是此题解题方法比较简单,只要将区间分隔成各个点,每个点有两个属性,一个是值,一个是标志(0起点,1止点),然后对这些点排序,最后,从头开始扫描排序的结果,遇到起点重叠个数加1,遇到止点重叠个数减1,并且记录好重叠个数的最大值。

class Interval
{
	int start;
	int end;
	Interval(int a,int b)
	{
		start = a;
		end = b;
	}
}

class Point
{
	int value;
	int type;
	Point(int v,int t)
	{
		this.value = v;
		this.type = t;
	}
}

class Com implements Comparator<Point>
{
	public int compare(Point p1,Point p2)   //这个方法是看这个Point类中的value值
	{
		if(p1.value == p2.value)
			return 0;
		else if(p1.value > p2.value)   //如果前面那一个大于后面那一个,那么就要交换
			return 1;
		else 
			return -1;
	}
}

public class getOverlappingCount 
{
	public static int GetOverLappingCount(Interval[] A)
	{
		int max = 0,count = 1;    //这里count从1开始是因为计算的是重叠的区间,等于重叠区间个数加1
		if(A == null || A.length == 0)
			return max;
		ArrayList<Point> list = new ArrayList<Point>();
		for(int i = 0; i < A.length; i++)
		{
			list.add(new Point(A[i].start,0));
			list.add(new Point(A[i].end,1)); 
		}
		Collections.sort(list,new Com());
		for(int i = 0; i < list.size(); i++)
		{
			if(list.get(i).type == 0)
			{
				count++;
				if(count > 0)
				{
					max = Math.max(count, max);
				}
			}
			else
				count--;
			//System.out.println(count + " " + max);
		}
		return max;
	}
}

要将红黑树修改为区间树并实现重叠区间查找算法,同时依据 `insert.txt` 文件生成区间树,可以按照以下步骤进行: ### 1. 定义区间树节点类 首先,定义区间树的节点类,包含必要的属性,如左右子节点、父节点、颜色、最大端点值、区间的左右端点等。 ```python class IntervalTreeNode: def __init__(self, low, high): self.left = None self.right = None self.parent = None self.color = 0 # 0 表示红色,1 表示黑色 self.max = high self.low = low self.high = high ``` ### 2. 定义区间树类 实现区间树的基本操作,如插入、左旋、右旋、插入修复等,同时实现重叠区间查找算法。 ```python class IntervalTree: def __init__(self): self.nil = IntervalTreeNode(0, 0) self.nil.color = 1 self.root = self.nil def left_rotate(self, x): y = x.right x.right = y.left if y.left != self.nil: y.left.parent = x y.parent = x.parent if x.parent == self.nil: self.root = y elif x == x.parent.left: x.parent.left = y else: x.parent.right = y y.left = x x.parent = y self.update_max(x) self.update_max(y) def right_rotate(self, y): x = y.left y.left = x.right if x.right != self.nil: x.right.parent = y x.parent = y.parent if y.parent == self.nil: self.root = x elif y == y.parent.right: y.parent.right = x else: y.parent.left = x x.right = y y.parent = x self.update_max(y) self.update_max(x) def update_max(self, node): node.max = node.high if node.left != self.nil: node.max = max(node.max, node.left.max) if node.right != self.nil: node.max = max(node.max, node.right.max) def insert_fixup(self, z): while z.parent.color == 0: if z.parent == z.parent.parent.left: y = z.parent.parent.right if y.color == 0: z.parent.color = 1 y.color = 1 z.parent.parent.color = 0 z = z.parent.parent else: if z == z.parent.right: z = z.parent self.left_rotate(z) z.parent.color = 1 z.parent.parent.color = 0 self.right_rotate(z.parent.parent) else: y = z.parent.parent.left if y.color == 0: z.parent.color = 1 y.color = 1 z.parent.parent.color = 0 z = z.parent.parent else: if z == z.parent.left: z = z.parent self.right_rotate(z) z.parent.color = 1 z.parent.parent.color = 0 self.left_rotate(z.parent.parent) self.root.color = 1 def insert(self, low, high): z = IntervalTreeNode(low, high) y = self.nil x = self.root while x != self.nil: y = x if z.low < x.low: x = x.left else: x = x.right z.parent = y if y == self.nil: self.root = z elif z.low < y.low: y.left = z else: y.right = z z.left = self.nil z.right = self.nil z.color = 0 self.insert_fixup(z) self.update_max_path(z) def update_max_path(self, node): while node != self.nil: self.update_max(node) node = node.parent def interval_search(self, low, high): x = self.root while x != self.nil and not (x.low <= high and low <= x.high): if x.left != self.nil and x.left.max >= low: x = x.left else: x = x.right return x if x != self.nil else None ``` ### 3. 从文件中读取数据并构建区间树 读取 `insert.txt` 文件,根据文件内容插入区间到区间树中。 ```python def build_interval_tree_from_file(file_path): tree = IntervalTree() with open(file_path, 'r') as file: num_intervals = int(file.readline().strip()) for _ in range(num_intervals): line = file.readline().strip().split() low, high = int(line[0]), int(line[1]) tree.insert(low, high) return tree ``` ### 4. 示例使用 ```python file_path = 'insert.txt' interval_tree = build_interval_tree_from_file(file_path) # 示例查找重叠区间 search_low = 10 search_high = 20 result = interval_tree.interval_search(search_low, search_high) if result: print(f"找到重叠区间: [{result.low}, {result.high}]") else: print("未找到重叠区间") ``` ### 代码解释 - **IntervalTreeNode 类**:定义了区间树的节点结构,包含左右子节点、父节点、颜色、最大端点值、区间的左右端点等属性。 - **IntervalTree 类**:实现了区间树的基本操作,如左旋、右旋、插入、插入修复等,同时实现了重叠区间查找算法 `interval_search`。 - **build_interval_tree_from_file 函数**:从 `insert.txt` 文件中读取数据,构建区间树。 - **示例使用**:读取文件构建区间树,并进行重叠区间查找。 ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值