华为OD机试-区间叠加

发布时间 2023-08-13 20:12:42作者: 手握钢叉的猹

 

 

 

import java.util.ArrayList;
import java.util.TreeMap;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        Integer[][] lines = new Integer[5][2];
        lines[0] = new Integer[]{1, 4};
        lines[1] = new Integer[]{2, 5};
        lines[2] = new Integer[]{3, 6};
        lines[3] = new Integer[]{7, 8};
        lines[4] = new Integer[]{10, 39};
        TreeMap<Integer, ArrayList<Integer[]>> intervals = new TreeMap<>();

        // 建立点到线的映射
        for (Integer[] line : lines) {
            IntStream.range(line[0], line[1] + 1).forEach(idx -> {
                ArrayList<Integer[]> ints;
                if (intervals.containsKey(idx)) {
                    ints = intervals.get(idx);
                } else {
                    ints = new ArrayList<>();
                }
                ints.add(line);
                intervals.put(idx, ints);
            });
        }

        int total = 0;
        // 处理分段线段
        while (!intervals.isEmpty()) {
            ArrayList<Integer> matched = new ArrayList<>();
            total += retrieve(intervals.firstKey(), intervals, matched, 0);
            if (matched.isEmpty()) {
                break;
            } else {
                int maxIdx = matched.stream().mapToInt(Integer::intValue).max().orElse(-1);
                int maxRightIdx = intervals.get(maxIdx).stream().mapToInt(value -> value[1]).max().orElse(-1);
                for (int i = intervals.firstKey(); i <= maxRightIdx; i++) {
                    intervals.remove(i);
                }
            }
        }
        System.out.println(total);
    }

    // 下级线段判断
    private static int retrieve(Integer entryKey, TreeMap<Integer, ArrayList<Integer[]>> intervals, ArrayList<Integer> matched, int totalLine) {
        ArrayList<Integer[]> integers = intervals.get(entryKey);
        int nextOffset = integers.stream().mapToInt(position -> position[1] - entryKey).max().orElse(-1);
        int nextKey = entryKey + nextOffset;
        if (nextOffset != 0 && intervals.containsKey(nextKey)) {
            matched.add(entryKey);
            return retrieve(nextKey, intervals, matched, totalLine) + 1;
        } else {
            return totalLine;
        }
    }
}