一、贪心
- 贪心问题思路:对于每种情况,都是选择当前最优,比较短视。
- 只能解决单峰问题。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/53b64cfc95630b5360fc3fec9b409dd8.png)
二、区间选点问题
1、题目内容
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d73b4f8329d310eb2e7849ea78e66725.png)
2、算法思路
(1)图例
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0fc583f93f4de672a7632c9d1717069e.png)
(2)算法步骤
- 1、将每个区间按右端点从小到大排序。
- 2、从前往后一次枚举每一个区间,如果当前区间中已经包含点,则直接pass,否则,选择当前区间的右端点。
3、题解
import java.util.*;
import java.io.*;
public class Main{
static int N = 100010;
static int n;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String str1 = in.readLine();
n = Integer.parseInt(str1);
List<PIIs> list = new ArrayList<PIIs>();
for(int i = 0; i < n; i++){
String[] str2 = in.readLine().split(" ");
int l = Integer.parseInt(str2[0]);
int r = Integer.parseInt(str2[1]);
list.add(new PIIs(l, r));
}
Collections.sort(list);
int count = 0;
int end = Integer.MIN_VALUE;
for(PIIs item:list){
if(item.getFirst() > end){
count++;
end = item.getSecond();
}
}
System.out.println(count);
}
}
class PIIs implements Comparable<PIIs>{
private int first;
private int second;
public PIIs(int first,int second){
this.first = first;
this.second = second;
}
public int getFirst(){
return this.first;
}
public int getSecond(){
return this.second;
}
public int compareTo(PIIs o){
return Integer.compare(second, o.second);
}
}
三、最大不相交区间数量
1、题目内容
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/62a96a4e6711a93f7bdd19084be4dc60.png)
2、算法思路
(1)状态划分
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2d249778a6cc913f201d1dbbbee65cd7.png)
(2)步骤
-
- 将每一个区间按照右端点从小到大排序
-
- 从前向后依次排序每个区间,如果当前区间已经包含点,则直接pass,否则,选择当前区间的右端点。
(3)贪心证明
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3eff624a5abdcb8c7eb365421e635053.png)
3、题解
import java.util.*;
import java.io.*;
public class Main{
static int N = 100010;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String str1 = in.readLine();
int n = Integer.parseInt(str1);
List<PIIs> list = new ArrayList<PIIs>();
for(int i = 0; i < n; i++){
String[] str2 = in.readLine().split(" ");
int L = Integer.parseInt(str2[0]);
int R = Integer.parseInt(str2[1]);
list.add(new PIIs(L, R));
}
Collections.sort(list);
int count = 0;
int end = Integer.MIN_VALUE;
for(PIIs item:list){
if(item.getFirst() >end){
count++;
end = item.getSecond();
}
}
System.out.println(count);
}
}
class PIIs implements Comparable<PIIs>{
private int first;
private int second;
public PIIs(int first, int second){
this.first = first;
this.second = second;
}
public int getFirst(){
return this.first;
}
public int getSecond(){
return this.second;
}
public int compareTo(PIIs o){
return Integer.compare(second, o.second);
}
}
四、区间分组问题
1、题目内容
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/24a4b5706f90c65a8546bf4a91be166e.png)
2、算法思路
(1)状态划分
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/08c1c6c0d61c7fcf16d6ee24d0676805.png)
(2)算法步骤
-
- 将所有区间按照左端点从小到大排序
-
- 从前向后处理每个区间,判断能否能将其放入某个现有的组中,判断每个组区间的最后一个点是否与当前区间有交集,有则下一组。(L[i] > Max_R,L[i] <= Max_R则说明有交集)
(3)注意事项
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/fb565021d417615e370a69bb3f5fac9d.png)
3、题解
import java.util.*;
import java.io.*;
public class Main{
static int N = 100010;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String str1 = in.readLine();
int n = Integer.parseInt(str1);
List<PIIs> list = new ArrayList<PIIs>();
for(int i = 0; i < n; i++){
String[] str2 = in.readLine().split(" ");
int L = Integer.parseInt(str2[0]);
int R = Integer.parseInt(str2[1]);
list.add(new PIIs(L, R));
}
Collections.sort(list);
Queue<Integer> queue = new PriorityQueue<Integer>();
for(PIIs item:list){
if(queue.isEmpty() || queue.peek() >= item.getFirst()){
queue.offer(item.getSecond());
}else{
queue.poll();
queue.offer(item.getSecond());
}
}
System.out.println(queue.size());
}
}
class PIIs implements Comparable<PIIs>{
private int first;
private int second;
public PIIs(int first, int second){
this.first = first;
this.second = second;
}
public int getFirst(){
return this.first;
}
public int getSecond(){
return this.second;
}
public int compareTo(PIIs o){
return Integer.compare(first, o.first);
}
}
五、区间覆盖
1、题目内容
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3ecaa1f4730d1795b5f7f92a50cfbd5d.png)
2、算法步骤
1、状态划分
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9826fad8959f3b4db1e99690d6e911a5.png)
2、算法步骤
- 1. 将所有区间按左端点,从小到大排序
- 2. 从前往后一次枚举每个区间
-
-
3、题解
import java.util.*;
import java.io.*;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
List<PIIs> list = new ArrayList<PIIs>();
String[] str1 = in.readLine().split(" ");
int st = Integer.parseInt(str1[0]);
int ed = Integer.parseInt(str1[1]);
String str2 = in.readLine();
int n = Integer.parseInt(str2);
for(int i = 0; i < n; i++){
String[] str3 = in.readLine().split(" ");
int L = Integer.parseInt(str3[0]);
int R = Integer.parseInt(str3[1]);
list.add(new PIIs(L, R));
}
Collections.sort(list);
int res = 0;
boolean flag = false;
for(int i = 0; i < n; i++){
int j = i;
int end = Integer.MIN_VALUE;
while(j < n && list.get(j).getFirst() <= st){
end = Math.max(end, list.get(j).getSecond());
j++;
}
if(end < st){
res = -1;
break;
}
res++;
if(end >= ed){
flag = true;
break;
}
st = end;
i = j - 1;
}
if(!flag){
System.out.println(-1);
}else{
System.out.println(res);
}
}
}
class PIIs implements Comparable<PIIs>{
private int first;
private int second;
public PIIs(int first,int second){
this.first = first;
this.second = second;
}
public int getFirst(){
return this.first;
}
public int getSecond(){
return this.second;
}
public int compareTo(PIIs o){
return Integer.compare(first, o.first);
}
}