ACwing 算法基础 区间合并

13 篇文章 0 订阅

区间合并

介绍

区间合并是指有多个区间,其中某些区间是可以合并为一个区间的。如下图所示的两个区间,其左区间右端点和右区间的左端点是交叉的,所以这两个区间就可以合并。
在这里插入图片描述
我们首先通过区间的左端点进行排序,这样两个区间一共有三种情况:

  • 如果1区间的右端点大于2区间的左端点,如果1区间的右端点大于2区间的右端点,则两个区间可以合并为1区间。
    在这里插入图片描述
  • 如果1区间的右端点大于2区间的左端点,如果1区间的右端点小于2区间的右端点,则两个区间可以合并为1区间的左端点和2区间的右端点组成的一个新区间

在这里插入图片描述

  • 如果1区间的右端点小于2区间的左端点,那么两个区间无法合并

在这里插入图片描述

例题 区间合并

给定 n 个区间 [li,ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[1,3]和[2,6]可以合并为一个区间[1,6]。

import java.util.*;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;

class Reader{
    static BufferedReader buffer;
    static StringTokenizer token;
    static void init(InputStream input){
        buffer = new BufferedReader(new InputStreamReader(input));
        token = new StringTokenizer("");
    }
    static String next()throws IOException{
        while(!token.hasMoreTokens()){
            token = new StringTokenizer(buffer.readLine());
        }
        return token.nextToken();
    }
    static int nextInt() throws IOException{
        return Integer.parseInt(next());
    }
}
class TwoTuple<A,B>{
    public A first;
    public B second;
    public TwoTuple(A a,B b){
        this.first = a;
        this.second = b;
    }
}
public class Main{
    private static List<TwoTuple<Integer,Integer>> nums = new ArrayList<>();
    public static List<TwoTuple<Integer,Integer>> merge(List<TwoTuple<Integer,Integer>> lists){
        int st = -2000000000,ed = -2000000000;//设置初始位,判断是否区间为空
        List<TwoTuple<Integer,Integer>> ans = new ArrayList<>();
        for(TwoTuple<Integer,Integer> m : nums){
        //判断是否为情况3
            if(m.first > ed){
            // 判断是否为第一次插入
                if(st != -2000000000){
                	//若不是则将区间插入答案
                    ans.add(new TwoTuple<Integer,Integer>(st,ed)); 
                }
                st = m.first;
                ed = m.second;
            }else{
            //判断属于情况1还是情况2
                ed = Math.max(ed,m.second);
            }
        }
        if(st != -2000000000){ans.add(new TwoTuple<Integer,Integer>(st,ed));};
        return ans;
    }
    public static void main(String[] args) throws IOException{
        Reader.init(System.in);
        int n = Reader.nextInt();
        for(int i = 0; i < n; i++){
            nums.add(new TwoTuple<Integer,Integer>(Reader.nextInt(),Reader.nextInt()));
        }
        Collections.sort(nums,new Comparator<TwoTuple<Integer,Integer>>(){
           @Override
           public int compare(TwoTuple<Integer,Integer> a,TwoTuple<Integer,Integer> b){
               if(a.first != b.first) return a.first-b.first;
               else return a.second - b.second;
           }
        });//将输入排序,首先以左端点排序,如果左端点相等则以右端点排序。
        List<TwoTuple<Integer,Integer>> ans = merge(nums);
        System.out.print(ans.size());
    }
}










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值