给定N个闭区间[ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。
输出最小组数。
输入格式
第一行包含整数N,表示区间数。
接下来N行,每行包含两个整数ai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示最小组数。
数据范围
1≤N≤10^5,
−109≤ai≤bi≤10^9
输入样例:
3
-1 1
2 4
3 5
输出样例:
2
算法思想:
维护每组的最大右端点,新来的右端点与每组比大小,打了更新该组,小了新开一组,使用小根堆来维护最小组的值。
注:如果使用数组会导致超时。
超时代码!
import java.io.*;
import java.lang.*;
import java.util.*;
class Main{
static int n = 0, N = 100010;
static int[] groups = new int[N];
static int group = 0;
public static void main(String[] args)throws Exception{
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
n = Integer.valueOf(buf.readLine());
int[][] nums = new int[n][2];
int t = 0;
while(n-- != 0){
String[] info = buf.readLine().split(" ");
int a = Integer.valueOf(info[0]);
int b = Integer.valueOf(info[1]);
nums[t][0] = a;
nums[t][1] = b;
t++;
}
Arrays.fill(groups, -0x3f3f3f3f);
Arrays.sort(nums, (a,b)->{return a[0] - b[0];});//排序
for(int i = 0; i < t; ++i){
boolean flag = false;
for(int j = 0; j <= group; ++j){
if(nums[i][0] > groups[j]){
flag = true;
groups[j] = nums[i][1];
break;
}
}
if(!flag)groups[++group] = nums[i][1];
}
System.out.print(group + 1);
}
}
小根堆优化代码!
import java.io.*;
import java.lang.*;
import java.util.*;
class Main{
static int n = 0, N = 100010;
static PriorityQueue<Integer> qu = new PriorityQueue<>();
public static void main(String[] args)throws Exception{
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
n = Integer.valueOf(buf.readLine());
int[][] nums = new int[n][2];
int t = 0;
while(n-- != 0){
String[] info = buf.readLine().split(" ");
int a = Integer.valueOf(info[0]);
int b = Integer.valueOf(info[1]);
nums[t][0] = a;
nums[t][1] = b;
t++;
}
Arrays.sort(nums, (a,b)->{return a[0] - b[0];});//排序
for(int i = 0; i < t; ++i){
if(qu.isEmpty() || qu.peek() >= nums[i][0]){
qu.offer(nums[i][1]);
}else if(qu.peek() < nums[i][0]){
qu.poll();
qu.offer(nums[i][1]);
}
}
System.out.print(qu.size());
}
}