最大线段重合问题(用堆实现)

简介: 最大线段重合问题(用堆实现)

题目

给定很多线段,每个线段都有两个数[start, end],表示线段开始位置和结束位置,左右都是闭区间。
规定:
1)线段的开始和结束位置一定都是整数值
2)线段重合区域的长度必须>=1
返回线段最多重合区域中,包含了几条线段

认真分析题目,可以发现任何一个重合区域的左边界 必定是某个线段的左边界

题解步骤:
1.把所有线段根据开始位置从小到大排好序
2.遍历所有线段,在小根堆中弹出所有<=开始位置的值
3.把线段的结束位置加入到小根堆中
4.小根堆中有几个数,就是这个线段的答案
5.返回所有线段中答案的最大值

所有线段根据开始位置从小大到大排好序这一步,我们不必自己写排序,可以用比较器,,

代码:

package com.harrison.class04;

import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;

/**
 * @author Harrison
 * @create 2022-03-02-21:17
 * @motto 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
 */
public class Code06_MaxCover {
    // 1.把所有线段根据开始位置从小到大排好序
    // 2.遍历所有线段,在小根堆中弹出所有<=开始位置的值
    // 3.把线段的结束位置加入到小根堆中
    // 4.小根堆中有几个数,就是这个线段的答案

    //

    public static int maxCover1(int[][] lines){
        int min=Integer.MAX_VALUE;
        int max=Integer.MIN_VALUE;
        for(int i=0; i<lines.length; i++){
            min=Math.min(min,lines[i][0]);
            max=Math.max(max,lines[i][1]);
        }
        int cover=0;
        for(double p=min+0.5; p<max; p+=1){
            int cur=0;
            for(int i=0; i<lines.length; i++){
                if(p>lines[i][0] && p<lines[i][1]){
                    cur++;
                }
            }
            cover=Math.max(cover,cur);
        }
        return cover;
    }

    public static int maxCover2(int[][] m){
        Line[] lines=new Line[m.length];
        for(int i=0; i<lines.length; i++){
            lines[i]=new Line(m[i][0],m[i][1]);
        }
        Arrays.sort(lines,new StartComparator());
        PriorityQueue<Integer> heap=new PriorityQueue<>();
        int max=0;
        for(int i=0; i<lines.length; i++){
            while(!heap.isEmpty() && heap.peek()<=lines[i].start){
                heap.poll();
            }
            heap.add(lines[i].end);
            max=Math.max(max,heap.size());
        }
        return max;
    }

    public static class Line{
        public int start;
        public int end;

        public Line(int s,int e){
            start=s;
            end=e;
        }
    }

    public static class StartComparator implements Comparator<Line>{
        public int compare(Line l1,Line l2){
            return l1.start-l2.start;
        }
    }

    public static int[][] generateLines(int N,int L,int R){
        int size=(int)(Math.random()*N)+1;
        int[][] ans=new int[size][2];
        for(int i=0; i<ans.length; i++){
            int a=L+(int)(Math.random()*(R-L+1));
            int b=L+(int)(Math.random()*(R-L+1));
            if(a==b){
                b=a+1;
            }
            ans[i][0]= Math.min(a,b);
            ans[i][1]=Math.max(a,b);
        }
        return ans;
    }

    public static void main(String[] args) {
        int N=100;
        int L=0;
        int R=200;
        int testTimes=100000;
        System.out.println("test begin");
        for(int i=0; i<testTimes; i++){
            int[][] lines=generateLines(N,L,R);
            int ans1=maxCover1(lines);
            int ans2=maxCover2(lines);
            if(ans1!=ans2){
                System.out.println("oops");
            }
        }
        System.out.println("test finish");
    }
}
相关文章
|
敏捷开发 Java 测试技术
探索软件测试中的自动化:从基础到高级应用
在软件工程的广阔领域中,自动化测试以其高效、可靠和可重复的特性成为提升软件开发质量的关键手段。本文旨在通过实际案例和代码示例,引导读者理解自动化测试的基本概念,掌握其在不同阶段的应用,并最终能够独立设计和实施高效的自动化测试策略。
|
网络协议
阿里云服务器搭建DNS解析服务步骤
在阿里云搭建DNS解析服务,首先注册阿里云账号并购买适合的云服务器。获取服务器公网IP后,配置服务器并安装DNS软件如Bind9。接着设置DNS解析,包括定义顶级和子域名的指向。最后,通过ping测试或浏览器访问验证DNS解析功能是否正常。
1494 19
MASM32写的免费软件“ProcView/系统进程监控” V1.4.4003 说明和下载
MASM32写的免费软件“ProcView/系统进程监控” V1.4.4003 说明和下载
|
存储 开发工具 git
Git常用命令汇总
这是Git命令速查表,涵盖从版本库创建、文件添加与提交、状态查询到分支管理、标签创建及撤销操作的各项常用指令。同时介绍了如何通过GitHub进行代码仓库的创建与同步,帮助用户高效地使用Git进行版本控制和协作开发。
157 0
Git常用命令汇总
|
算法 C语言 C++
刷题训练之位运算
刷题训练之位运算
70 0
数据结构之堆的实现(图解➕源代码)
数据结构之堆的实现(图解➕源代码)
|
安全 算法 数据安全/隐私保护
BGP高级特性
BGP高级特性
|
运维 Kubernetes Cloud Native
「开源人说」| 开源项目的演进会遇到哪些“坑”?KubeVela 从发起到晋级 CNCF 孵化的全程回顾
KubeVela 诞生于 OAM 社区,开源第一天起就遵循“社区发起、开放治理、国际化运作”的原则。 今 年 2 月,KubeVela 经过全体 ToC 投票成功进入 CNCF Incubation,是云原生领域首个晋级孵化的面向应用的交付和管理平台。本文将做一个完整的回顾,梳理项目演进过程中的那些“坑”,希望对整个开源生态的发展有所帮助。
48607 1
「开源人说」| 开源项目的演进会遇到哪些“坑”?KubeVela 从发起到晋级 CNCF 孵化的全程回顾
|
关系型数据库 MySQL 数据库
Docker安装MySQL并使用Navicat连接
Docker安装MySQL并使用Navicat连接
1782 0
Docker安装MySQL并使用Navicat连接
|
JavaScript 大数据
Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo
上一篇的demo使用隐藏js代码的方式,实现了一个饼图的基本交互方式,并预留了Qt模块对外的基础接口。   本篇的demo实现了自动排序的柱状图,实现了一个自动排序柱状图的基本交互方式,即Qt调用js脚本操作html。   本篇demo使用Qt定时器方式,实现数据定时刷新自增,并预留出了定时器间隔参数。   像大数据网页常看的人口增长时间图,收入年度增长时间图等都是这一类。
Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo