华为OD机试真题——区间交集(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
2025 B卷 200分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《区间交集》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C
GO
更多内容
题目名称:区间交集
- 知识点:区间合并、排序、贪心算法
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
给定一组闭区间,其中部分区间存在交集。任意两个给定区间的交集称为公共区间(例如:[1,2]
和[2,3]
的公共区间为[2,2]
;[3,5]
和[3,6]
的公共区间为[3,5]
)。若公共区间之间存在交集,则需要合并(例如:[1,3]
和[3,5]
的公共区间为[3,3]
,需合并为[1,5]
)。最终按升序排列输出合并后的区间列表。
输入描述
- 一组区间列表,区间数 ( N ) 满足 ( 0 \leq N \leq 1000 );
- 区间元素 ( X ) 满足 ( -10000 \leq X \leq 10000 )。
输出描述
升序排列的合并后区间列表。若结果为空或输入区间数少于2个,输出None
。
示例
输入:
[[0,3],[1,3],[3,5],[3,6]]
输出:
[[1,5]]
说明:
- 所有两两区间的公共区间为
[1,3]
、[3,3]
、[3,5]
,合并后得到[1,5]
。
Java
问题分析
题目要求找出所有两两区间的公共区间,合并这些公共区间后输出结果。若结果为空或输入区间数少于2个,输出None。
解题思路
- 生成公共区间:遍历所有两两区间,计算它们的交集。
- 合并区间:按起始点排序后合并重叠或相邻的公共区间。
- 输出处理:根据条件判断是否输出None或合并后的结果。
代码实现
import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String input = sc.nextLine().trim();List<int[]> intervals = parseInput(input);// 输入区间数小于2,直接输出Noneif (intervals.size() < 2) {System.out.println("None");return;}// 生成所有两两区间的公共区间List<int[]> commonIntervals = new ArrayList<>();for (int i = 0; i < intervals.size(); i++) {for (int j = i + 1; j < intervals.size(); j++) {int[] a = intervals.get(i);int[] b = intervals.get(j);int start = Math.max(a[0], b[0]);int end = Math.min(a[1], b[1]);if (start <= end) {commonIntervals.add(new int[]{start, end});}}}// 若公共区间为空,输出Noneif (commonIntervals.isEmpty()) {System.out.println("None");return;}// 合并公共区间mergeIntervals(commonIntervals);// 输出结果System.out.println(formatOutput(commonIntervals));}// 解析输入字符串为区间列表private static List<int[]> parseInput(String input) {List<int[]> intervals = new ArrayList<>();if (input.isEmpty() || input.equals("[]")) return intervals;String content = input.substring(1, input.length() - 1);String[] parts = content.split("\\],\\[");for (String part : parts) {String[] nums = part.split(",");int start = Integer.parseInt(nums[0]);int end = Integer.parseInt(nums[1]);intervals.add(new int[]{start, end});}return intervals;}// 合并重叠或相邻的区间private static void mergeIntervals(List<int[]> intervals) {intervals.sort((a, b) -> a[0] - b[0]);List<int[]> merged = new ArrayList<>();merged.add(intervals.get(0));for (int i = 1; i < intervals.size(); i++) {int[] last = merged.get(merged.size() - 1);int[] curr = intervals.get(i);if (curr[0] <= last[1]) {last[1] = Math.max(last[1], curr[1]);} else {merged.add(curr);}}intervals.clear();intervals.addAll(merged);}// 格式化输出为字符串private static String formatOutput(List<int[]> intervals) {if (intervals.isEmpty()) return "None";StringBuilder sb = new StringBuilder("[");for (int i = 0; i < intervals.size(); i++) {sb.append("[").append(intervals.get(i)[0]).append(",").append(intervals.get(i)[1]).append("]");if (i != intervals.size() - 1) sb.append(",");}sb.append("]");return sb.toString();}
}
代码详解
-
输入解析:
parseInput
方法将输入字符串解析为区间列表。例如,输入"[[0,3],[1,3]]"
转换为List<int[]>
。
-
生成公共区间:
- 双重循环遍历所有区间对,计算它们的交集。例如,
[0,3]
和[1,3]
的交集是[1,3]
。
- 双重循环遍历所有区间对,计算它们的交集。例如,
-
合并区间:
- 将公共区间按起始点排序,合并重叠部分。例如,
[1,3]
和[3,5]
合并为[1,5]
。
- 将公共区间按起始点排序,合并重叠部分。例如,
-
输出处理:
formatOutput
将合并后的区间列表转换为字符串格式。例如,合并后的列表[[1,5]]
转换为"[[1,5]]"
。
示例测试
-
输入1:
[[0,3],[1,3],[3,5],[3,6]]
输出:
[[1,5]]
说明:公共区间合并后为
[1,5]
。 -
输入2:
[[1,2],[3,4]]
输出:
None
说明:公共区间为空。
-
输入3:
[[1,3],[2,4],[5,7]]
输出:
[[2,3],[5,7]]
说明:公共区间
[1,3]
和[2,4]
合并为[2,3]
,[5,7]
独立。
综合分析
-
时间复杂度:
- 生成公共区间:O(N²),遍历所有两两区间对。
- 合并区间:O(M log M),M为公共区间数。
-
空间复杂度:
- O(N²),存储所有公共区间。
-
正确性:
- 严格计算交集和合并逻辑,确保结果正确。
-
适用性:
- 适用于区间数≤1000的情况,满足题目限制。
-
优势:
- 高效性:通过排序和线性合并提高效率。
- 鲁棒性:处理各种边界条件,如空输入或单区间输入。
python
问题分析
题目要求找出所有两两区间的公共区间,合并这些公共区间后输出结果。若结果为空或输入区间数少于2个,输出 None
。
解题思路
- 生成公共区间:遍历所有两两区间对,计算它们的交集。
- 合并区间:将所有公共区间按起始点排序后合并重叠部分。
- 输出处理:根据条件判断是否输出
None
或合并后的结果。
代码实现
import sys
from itertools import combinationsdef main():# 读取输入并解析为区间列表input_str = sys.stdin.read().strip()if not input_str or input_str == "[]":print("None")returnintervals = eval(input_str) # 将输入字符串转为列表(实际应用建议用更安全的方法)intervals = [tuple(interval) for interval in intervals]# 输入区间数小于2,直接输出Noneif len(intervals) < 2:print("None")return# 生成所有两两区间的公共区间common = []for (a_start, a_end), (b_start, b_end) in combinations(intervals, 2):start = max(a_start, b_start)end = min(a_end, b_end)if start <= end:common.append(