全网最全面的华为OD机试真题汇总,100%原题题库,不需要开会员即可查看全部内容,更多考题请查看真题库。
真题库:https://www.yuque.com/codernav.com/od
题目:区间连接器
知识点数组排序滑窗
时间限制:1s 空间限制:256MB 限定语言:不限
题目描述:
有一组区间 [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]
示例1
输入:
[1,10],[15,20],[18,30],[33,40]
[5,4,3,2]
输出:
1
说明:
合并后:[1,10], [15,30], [33,40],使用 5, 3 两个连接器连接后只剩下 [1,40]
示例2
输入:
[1,2],[3,5],[7,10],[15,20],[30,100]
[5,4,3,2,1]
输出:
2
说明:
无重叠和相邻,使用 1,2, 5 三个连接器连接后只剩下 [1, 20], [30, 100]
解题思路:
1、对区间进行升序排序;
2、将相邻和存在交集的区间进行合并。
3、求得步骤2中各区间的距离集合
4、将步骤3的集合与连接器集合进行比较
注:使用过的连接器不能继续使用;连接器取最接近的。
代码实现一:
package com.codernav.demo.hwod.exam; import java.util.*; /** * @title 区间连接器 * @Description 有一组区间 [a0, b0], [a1, b1], ... (a, b 表示起点, 终点),区间有可能重叠、相邻,重叠或相邻则可以合并为更大的区间; * 给定一组连接器[x1, x2, x3, ...](x 表示连接器的最大可连接长度,即 x>=gap),可用于将分离的区间连接起来, * 但两个分离区间之间只能使用1个连接器;请编程实现使用连接器后,最少的区间数结果。 * @Author 开发者导航 * @website https://codernav.com * @date 2023/5/28 */ public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String[] regionsStr = sc.nextLine().replaceAll("\\[", "").replaceAll("]", "").split(","); String[] linksStr = sc.nextLine().replaceAll("\\[", "").replaceAll("]", "").split(","); List<int[]> regions = new ArrayList<>(); //区间集合 for (int i = 0; i < regionsStr.length; i += 2) { int left = Integer.parseInt(regionsStr[i]); int right = Integer.parseInt(regionsStr[i + 1]); regions.add(new int[]{left, right}); } List<Integer> links = new ArrayList<>(); //连接器集合 for (String s : linksStr) { links.add(Integer.valueOf(s)); } regions.sort((a, b) -> { //区间进行升序排序 if (b[0] == a[0]) { return a[1] - b[1]; } return a[0] - b[0]; }); int[] region = null; Iterator<int[]> iter = regions.iterator(); while (iter.hasNext()) { int[] next = iter.next(); if (region == null) { region = next; } else if (region[1] >= next[0]) { if (region[1] < next[1]) { region[1] = next[1]; } iter.remove(); } else { region = next; } } List<Integer> gaps = new ArrayList<>(); //各区间所需连接器的长度集合 iter = regions.iterator(); region = null; while (iter.hasNext()) { int[] next = iter.next(); if (region != null) { int gap = next[0] - region[1]; gaps.add(gap); } region = next; } Collections.sort(gaps); Collections.sort(links); int i = 0; // gaps index int j = 0; // links index while (i < gaps.size() && j < links.size()) { if (links.get(j) >= gaps.get(i)) { //连接器长度大于等于所需连接器长度,符合要求 gaps.set(i, 0); //可以连接的两个区间距离设置为0 i++; j++; //使用过的连接器不再使用 } else { j++; } } int noneZoreNum = 0; for (int g : gaps) { if (g > 0) { //大于0,说明两个区间无法进行连接 noneZoreNum++; } } System.out.println(noneZoreNum + 1); } }
代码实现二:Java代码满分实现
package com.codernav.demo.hwod.exam; import java.util.*; /** * @title 区间连接器 * @Description 有一组区间 [a0, b0], [a1, b1], ... (a, b 表示起点, 终点),区间有可能重叠、相邻,重叠或相邻则可以合并为更大的区间; * 给定一组连接器[x1, x2, x3, ...](x 表示连接器的最大可连接长度,即 x>=gap),可用于将分离的区间连接起来, * 但两个分离区间之间只能使用1个连接器;请编程实现使用连接器后,最少的区间数结果。 * @Author 开发者导航 * @website https://codernav.com * @date 2023/5/28 */ public class Main{ public static void main(String[] args) throws Exception { Scanner in = new Scanner(System.in); String regionsStr = in.nextLine(); String linksStr = in.nextLine(); List<int[]> regions = new ArrayList<>(); StringTokenizer st = new StringTokenizer(regionsStr, ",[]"); while(st.hasMoreTokens()) { int lo = Integer.parseInt(st.nextToken()); int hi = Integer.parseInt(st.nextToken()); regions.add(new int[]{lo, hi}); } List<Integer> links = new ArrayList<>(); st = new StringTokenizer(linksStr, ",[]"); while(st.hasMoreTokens()) { int link = Integer.parseInt(st.nextToken()); links.add(link); } regions.sort((a, b) -> { return a[0] > b[0] ? 1 : a[0] < b[0] ? -1 : 0; }); int[] region = null; Iterator<int[]> iter = regions.iterator(); while(iter.hasNext()) { int[] next = iter.next(); if(region == null) { region = next; } else if(region[1] >= next[0]) { if(region[1] < next[1]) { region[1] = next[1]; } iter.remove(); } else { region = next; } } List<Integer> gaps = new ArrayList<>(); iter = regions.iterator(); region = null; while(iter.hasNext()) { int[] next = iter.next(); if(region != null) { int gap = next[0] - region[1]; gaps.add(gap); } region = next; } Collections.sort(gaps); Collections.sort(links); int i = 0; // gaps index int j = 0; // links index while(i < gaps.size() && j < links.size()) { if(links.get(j) >= gaps.get(i)) { gaps.set(i, 0); i++; j++; } else { j++; } } int noneZoreNum = 0; for (int g : gaps) { if(g > 0) { noneZoreNum++; } }; System.out.println(noneZoreNum + 1); } }