贪心 - 区间问题 - 最大不相交区间数量

417 阅读1分钟
  • 问题背景

给定 N 个闭区间 [ai,bi],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。

输出可选取区间的最大数量。

  • 策略
    • 将每个区间按右端点从小到大排序
    • 从前往后依次枚举每个区间
      • 如果当前区间中已经包含点,则直接pass
      • 否则,选择当前区间,并将其右端点作为当前区间的代表

练习

01 最大不相交区间数量

  • 题目

Snipaste_2023-04-03_19-15-28.png

  • 题解
import java.io.*;
import java.util.*;

public class Main {
    public static final int N = 100010;
    public static int n;
    public static Pair[] range = new Pair[N];

    public static class Pair implements Comparable<Pair> {
        public int first;
        public int second;

        public Pair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public int compareTo(Pair o) {
            return this.second - o.second;
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
        n = Integer.parseInt(br.readLine());
        for (int i = 0; i < n; i++) {
            String[] str1 = br.readLine().split(" ");
            range[i] = new Pair(Integer.parseInt(str1[0]), Integer.parseInt(str1[1]));
        }
        //将所有区间按照右端点排序
        Arrays.sort(range, 0, n);

        int res = 0;
        //记录一个区间的右端点来代表这个区间
        int ed = -0x3f3f3f3f;

        //遍历所有区间
        for (int i = 0; i < n; i++) {
            //如果最后一个选取的区间的右端点不在当前区间内
            if (ed < range[i].first) {
                //选取当前区间 并记录这个区间的右端点
                res++;
                ed = range[i].second;
            }
        }
        pw.println(res);
        pw.close();
        br.close();
    }
}