Loading

算法题:合并区间

题目

输入多个区间,输出所有区间的长度之和(注意要取所有区间的并集)。java实现

比如输入 [0,2],[3,6],[1,5], 输出6

解法

排序合并法: 先对区间排序,然后合并重叠区间,最后计算总长度。

import java.util.*;

public class IntervalUnionLength {
    
    public static int getUnionLength(int[][] intervals) {
        if (intervals == null || intervals.length == 0) {
            return 0;
        }
        
        // 1. 按照区间起始点排序
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        
        // 2. 合并区间
        List<int[]> merged = new ArrayList<>();
        int[] current = intervals[0];
        
        for (int i = 1; i < intervals.length; i++) {
            int[] next = intervals[i];
            
            // 如果当前区间与下一个区间有重叠
            if (current[1] >= next[0]) {
                // 合并区间:取最大的结束点
                current[1] = Math.max(current[1], next[1]);
            } else {
                // 没有重叠,保存当前区间,开始处理下一个区间
                merged.add(current);
                current = next;
            }
        }
        // 添加最后一个区间
        merged.add(current);
        
        // 3. 计算并集总长度
        int totalLength = 0;
        for (int[] interval : merged) {
            totalLength += interval[1] - interval[0];
        }
        
        return totalLength;
    }
    
    // 另一种更简洁的写法
    public static int getUnionLength2(int[][] intervals) {
        if (intervals == null || intervals.length == 0) {
            return 0;
        }
        
        // 按照起始点排序
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        
        int totalLength = 0;
        int currentStart = intervals[0][0];
        int currentEnd = intervals[0][1];
        
        for (int i = 1; i < intervals.length; i++) {
            int[] interval = intervals[i];
            
            if (interval[0] <= currentEnd) {
                // 有重叠,更新结束点
                currentEnd = Math.max(currentEnd, interval[1]);
            } else {
                // 没有重叠,计算当前区间长度并累加
                totalLength += currentEnd - currentStart;
                // 开始新的区间
                currentStart = interval[0];
                currentEnd = interval[1];
            }
        }
        
        // 加上最后一个区间
        totalLength += currentEnd - currentStart;
        
        return totalLength;
    }
    
    public static void main(String[] args) {
        // 测试用例: [0,2], [3,6], [1,5]
        int[][] intervals = {
            {0, 2},
            {3, 6},
            {1, 5}
        };
        
        System.out.println("方法一结果: " + getUnionLength(intervals)); // 输出: 6
        
        // 验证结果
        System.out.println("方法二结果: " + getUnionLength2(intervals)); // 输出: 6
        
        // 更多测试用例
        testCases();
    }
    
    private static void testCases() {
        System.out.println("\n更多测试用例:");
        
        // 测试用例1: 完全重叠的区间
        int[][] test1 = {{1, 5}, {2, 4}, {3, 6}};
        System.out.println("测试1 [[1,5],[2,4],[3,6]]: " + getUnionLength(test1)); // 应该输出5
        
        // 测试用例2: 不重叠的区间
        int[][] test2 = {{0, 1}, {2, 3}, {4, 5}};
        System.out.println("测试2 [[0,1],[2,3],[4,5]]: " + getUnionLength(test2)); // 应该输出3
        
        // 测试用例3: 单个区间
        int[][] test3 = {{1, 10}};
        System.out.println("测试3 [[1,10]]: " + getUnionLength(test3)); // 应该输出9
        
        // 测试用例4: 空数组
        int[][] test4 = {};
        System.out.println("测试4 []: " + getUnionLength(test4)); // 应该输出0
        
        // 测试用例5: 包含负数的区间
        int[][] test5 = {{-5, -2}, {-3, 1}, {0, 4}};
        System.out.println("测试5 [[-5,-2],[-3,1],[0,4]]: " + getUnionLength(test5)); // 应该输出9
    }
}
posted @ 2025-12-25 22:30  拾月凄辰  阅读(3)  评论(0)    收藏  举报