区间合并
介绍
区间合并是指有多个区间,其中某些区间是可以合并为一个区间的。如下图所示的两个区间,其左区间右端点和右区间的左端点是交叉的,所以这两个区间就可以合并。
我们首先通过区间的左端点进行排序,这样两个区间一共有三种情况:
- 如果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());
}
}