华为OD机试真题——区间交集(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

发布于:2025-05-27 ⋅ 阅读:(22) ⋅ 点赞:(0)

在这里插入图片描述

2025 B卷 200分 题型

本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享

华为OD机试真题《区间交集》:


文章快捷目录

题目描述及说明

Java

python

JavaScript

C

GO

更多内容


题目名称:区间交集


  1. 知识点:区间合并、排序、贪心算法
  2. 时间限制:1秒
  3. 空间限制:256MB
  4. 限定语言:不限

题目描述

给定一组闭区间,其中部分区间存在交集。任意两个给定区间的交集称为公共区间(例如:[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。


解题思路

  1. 生成公共区间:遍历所有两两区间,计算它们的交集。
  2. 合并区间:按起始点排序后合并重叠或相邻的公共区间。
  3. 输出处理:根据条件判断是否输出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();
    }
}

代码详解

  1. 输入解析

    • parseInput 方法将输入字符串解析为区间列表。例如,输入 "[[0,3],[1,3]]" 转换为 List<int[]>
  2. 生成公共区间

    • 双重循环遍历所有区间对,计算它们的交集。例如,[0,3][1,3] 的交集是 [1,3]
  3. 合并区间

    • 将公共区间按起始点排序,合并重叠部分。例如,[1,3][3,5] 合并为 [1,5]
  4. 输出处理

    • formatOutput 将合并后的区间列表转换为字符串格式。例如,合并后的列表 [[1,5]] 转换为 "[[1,5]]"

示例测试

  1. 输入1

    [[0,3],[1,3],[3,5],[3,6]]  
    

    输出

    [[1,5]]
    

    说明:公共区间合并后为 [1,5]

  2. 输入2

    [[1,2],[3,4]]  
    

    输出

    None  
    

    说明:公共区间为空。

  3. 输入3

    [[1,3],[2,4],[5,7]]  
    

    输出

    [[2,3],[5,7]]  
    

    说明:公共区间 [1,3][2,4] 合并为 [2,3][5,7] 独立。


综合分析

  1. 时间复杂度

    • 生成公共区间:O(N²),遍历所有两两区间对。
    • 合并区间:O(M log M),M为公共区间数。
  2. 空间复杂度

    • O(N²),存储所有公共区间。
  3. 正确性

    • 严格计算交集和合并逻辑,确保结果正确。
  4. 适用性

    • 适用于区间数≤1000的情况,满足题目限制。
  5. 优势

    • 高效性:通过排序和线性合并提高效率。
    • 鲁棒性:处理各种边界条件,如空输入或单区间输入。

python

问题分析

题目要求找出所有两两区间的公共区间,合并这些公共区间后输出结果。若结果为空或输入区间数少于2个,输出 None


解题思路

  1. 生成公共区间:遍历所有两两区间对,计算它们的交集。
  2. 合并区间:将所有公共区间按起始点排序后合并重叠部分。
  3. 输出处理:根据条件判断是否输出 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(

网站公告

今日签到

点亮在社区的每一天
去签到