一、题目描述
有一组区间 [a0, b0], [a1, b1], … (a, b 表示起点, 终点),区间有可能重叠、相邻,重叠或相邻则可以合并为更大的区间;
给定一组连接器[x1, x2, x3, …](x 表示连接器的最大可连接长度,即 x>=gap),可用于将分离的区间连接起来,但两个分离区间之间只能使用1个连接器;
请编程实现使用连接器后,最少的区间数结果。
区间数量 <10000;a,b 均 <=10000;
连接器梳理 <10000; x <=10000;
二、输入描述
区间组:[1,10],[15,20],[18,30],[33,40]
连接器组:[5,4,3,2]
三、输出描述
1
说明:合并后:[1,10], [15,30], [33,40],使用 5, 3 两个连接器连接后只剩下 [1,40]
四、Java算法源码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 区间组
String line = sc.nextLine();
Integer[][] rangeArr = Arrays.stream(line.substring(1, line.length() - 1).split("],\\["))
.map(str -> Arrays.stream(str.split(",")).map(Integer::parseInt).toArray(Integer[]::new))
.toArray(Integer[][]::new);
// 连接器组
String nextLine = sc.nextLine();
List<Integer> connectList = Arrays.stream(nextLine.substring(1, nextLine.length() - 1).split(","))
.map(Integer::parseInt)
.collect(Collectors.toList());
Arrays.sort(rangeArr, Comparator.comparingInt(x -> x[0]));
LinkedList<Integer[]> mergeRanges = new LinkedList<Integer[]>();
mergeRanges.addLast(rangeArr[0]);
LinkedList<Integer> linked = new LinkedList<>();
for (int i = 1; i < rangeArr.length; i++) {
Integer[] last = mergeRanges.getLast();
int a = last[0];
int b = last[1];
Integer[] range = rangeArr[i];
int r1 = range[0];
int r2 = range[1];
if (r1 <= b) {
mergeRanges.removeLast();
mergeRanges.addLast(new Integer[]{a, Math.max(b, r2)});
} else {
linked.addLast(r1 - b);
mergeRanges.addLast(range);
}
}
linked.sort((a, b) -> b - a);
connectList.sort((a, b) -> b - a);
while (connectList.size() > 0 && linked.size() > 0) {
if (connectList.remove(connectList.size() - 1) >= linked.getLast()) {
linked.removeLast();
}
}
System.out.println(linked.size() + 1);
}
五、效果展示
1、输入
[1,10],[15,20],[18,30],[33,40]
[5,4,3,2]
2、输出
1
🏆下一篇:华为OD机试真题 Java 实现【获得完美走位】【2023Q1 100分】
🏆本文收录于,华为OD机试(JAVA)(2022&2023)
本专栏包含了最新最全的2023年华为OD机试真题,有详细的分析和Java解答。已帮助1000+同学顺利通过OD机考。专栏会持续更新,每天在线答疑。