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,直接输出None
if (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});
}
}
}
// 若公共区间为空,输出None
if (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 combinations
def main():
# 读取输入并解析为区间列表
input_str = sys.stdin.read().strip()
if not input_str or input_str == "[]":
print("None")
return
intervals = eval(input_str) # 将输入字符串转为列表(实际应用建议用更安全的方法)
intervals = [tuple(interval) for interval in intervals]
# 输入区间数小于2,直接输出None
if 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(