详解见注释
Big O
因为有了排序,所以需要$O(nlogn)$
Java 代码
//从左到右按照左端点排序
//对于排序的情况,----------- 此为给定的区间
// ----------
// --------
//在左端点可以覆盖给定区间的start情况下,更新,也就是双指针,当左端点不可以了也就跳出,而i从此继续开始
//又因为i是for loop会自动加一,所以j最后不满足,要j - 1 -> i, 这样i++ 又回到这个船新的位置
//同时这样判断的最大值r,需要检验几个点:1.极端条件,r < start,则最右边的都到不了,这样就量了。。
// 2.类似于1的极端条件,中间的时候,r未更新,也就是出现了 ---- -----的情况
// 没有了left < start的情况,全部都是left > start,这样的时候做不了了。。
// 3.r >= end需要检查,如果永远到不了的话,则没有意义,所以需要判断,可以设flag
// 4.flag有必要,因为可能走完所有的i,都到不了end,但会自动出来,所以要判断flag
import java.util.*;
public class Main {
public static void main(String[] agrs) {
Scanner sc = new Scanner(System.in);
int start = sc.nextInt();
int end = sc.nextInt();
int n = sc.nextInt();
Range[] range = new Range[n];
for (int i = 0; i < n; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
range[i] = new Range(a, b);
}
Arrays.sort(range, (a, b) -> a.l - b.l);
int res = 0;
boolean flag = false;
for (int i = 0; i < n; i++) {
int j = i;
int max_r = Integer.MIN_VALUE;
while (j < n && range[j].l <= start) { //双指针一定要先满足 •••j < n•••
max_r = Math.max(max_r, range[j].r);
j++;
}
if (max_r < start) {
//两种情况 : 1. -------
// ---- -- (压根进不来。。)
// 2. ---------
// ---- ---- (由于range[i].l < start 不成立,所以max_r得不到更新,因此依旧小于)
break;
}
//开始更新
res++; //更新完再看结果
if (max_r >= end) {
flag = true;
break;
}
start = max_r;
i = j - 1; //切记要更新。。。 而且因为i会自动+1所以j要往前退一位
}
if (flag) {
System.out.println(res);
} else {
System.out.println("-1");
}
}
}
class Range {
int l;
int r;
public Range(int l, int r) {
this.l = l;
this.r = r;
}
}