用c语言实现,力扣典型题目(56.合并区间),日常练习基本功

以数组intervals表示若干个区间的集合,其中单个区间为intervals[i]=[starti,endi】。请你合并所有
重叠的区间,并返▣一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
示例1:
输入:intervals=[[1,3],[2,6],[8,10],[15,18]
输出:[[1,6],[8,10],[15,18]]
解释:区间[1,3]和[2,6]重叠,将它们合并为[1,6].
示例2:
输:intervals=[[1,4],[4,5]]
输出:[[1,5]]
解释:区间[1,4]和[4,5]可被视为重叠区间。
提示:
.1<=intervals.length <104
intervals [i].length =2
·0<=start1<=end1<=104

设计思路

设计思路的完善主要涉及代码结构、算法逻辑、异常处理、内存管理等方面。

1. **函数拆分:** 将代码拆分成更小的函数,每个函数负责一个特定的功能。这样可以提高代码的可读性和可维护性。

2. **异常处理:** 在实际应用中,可能会遇到各种异常情况,例如内存分配失败、输入数据非法等。在代码中添加相应的异常处理机制,确保程序能够正确地处理各种情况。

3. **代码注释:** 添加清晰的注释,说明每个函数的作用、参数意义以及返回值。注释应该是清晰、简洁且易于理解的,有助于其他人理解你的代码。

4. **错误处理:** 在关键步骤添加错误处理机制,确保程序在发生错误时能够正确地处理,并返回合理的错误码或信息。

5. **内存管理:** 注意释放动态分配的内存,防止内存泄漏。在每次动态分配内存后,都要考虑如何在适当的时候释放这些内存。

6. **算法优化:** 如果可能的话,考虑对算法进行优化。合并区间的问题已经用排序和遍历相当有效的方式解决,但在一些特定情况下可能还有优化的空间。

7. **参数验证:** 在函数开始时验证输入参数的合法性,确保函数的输入是有效的。如果输入无效,可以返回错误码或采取适当的处理方式。

8. **适应性:** 代码应该具有一定的适应性,能够处理不同规模和形式的输入数据,而不仅仅局限于特定的情况。

9. **测试:** 编写有效的测试用例,确保代码在各种情况下都能正确运行。测试有助于发现潜在的问题并验证代码的正确性。

10. **命名规范:** 使用有意义的变量名和函数名,使得代码更易读。命名应该清晰地反映变量或函数的用途。

逐步实现

当然,让我们一步步分析这段代码。代码的目标是合并重叠的区间。下面是代码的主要结构和功能:

int main() {
    // 示例 1
    int intervals1[][2] = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};
    int size1 = sizeof(intervals1) / sizeof(intervals1[0]);
    int colSize1 = sizeof(intervals1[0]) / sizeof(int);

    int** result1;
    int returnSize1;
    int* returnColumnSizes1;
    result1 = merge((int**)intervals1, size1, &colSize1, &returnSize1, &returnColumnSizes1);

    printf("示例 1 输出: ");
    printIntervals(result1, returnSize1, returnColumnSizes1);

    // 释放内存
    for (int i = 0; i < returnSize1; i++) {
        free(result1[i]);
    }
    free(result1);
    free(returnColumnSizes1);

    // 示例 2
    int intervals2[][2] = {{1, 4}, {4, 5}};
    int size2 = sizeof(intervals2) / sizeof(intervals2[0]);
    int colSize2 = sizeof(intervals2[0]) / sizeof(int);

    int** result2;
    int returnSize2;
    int* returnColumnSizes2;
    result2 = merge((int**)intervals2, size2, &colSize2, &returnSize2, &returnColumnSizes2);

    printf("示例 2 输出: ");
    printIntervals(result2, returnSize2, returnColumnSizes2);

    // 释放内存
    for (int i = 0; i < returnSize2; i++) {
        free(result2[i]);
    }
    free(result2);
    free(returnColumnSizes2);

    return 0;
}

在主函数中,我们定义了两个示例,`intervals1`和`intervals2`,每个示例都是一个二维数组,表示一组区间。然后,我们调用 `merge` 函数来合并这些区间,并使用 `printIntervals` 函数打印结果。


int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes) {
    if (intervalsSize <= 1) {
        *returnSize = intervalsSize;
        *returnColumnSizes = intervalsColSize;
        return intervals;
    }

    // 按照区间的起始位置进行排序
    qsort(intervals, intervalsSize, sizeof(int*), compare);

    // 创建结果数组
    int** result = (int**)malloc(intervalsSize * sizeof(int*));
    *returnColumnSizes = (int*)malloc(intervalsSize * sizeof(int));
    int i, j;
    *returnSize = 0;

    // 遍历排序后的区间数组,逐个合并重叠的区间
    for (i = 0; i < intervalsSize; i++) {
        int currentStart = intervals[i][0];
        int currentEnd = intervals[i][1];

        // 合并重叠区间
        while (i < intervalsSize - 1 && currentEnd >= intervals[i + 1][0]) {
            i++;
            currentEnd = (currentEnd > intervals[i][1]) ? currentEnd : intervals[i][1];
        }

        // 将合并后的区间加入结果数组
        result[*returnSize] = (int*)malloc(2 * sizeof(int));
        result[*returnSize][0] = currentStart;
        result[*returnSize][1] = currentEnd;
        (*returnColumnSizes)[*returnSize] = 2;
        (*returnSize)++;
    }

    return result;
}

这个函数接收一个二维整数数组 `intervals`,数组的大小 `intervalsSize`,每个子数组的列数 `intervalsColSize`,以及三个输出参数:`returnSize` 表示合并后的区间数组的大小,`returnColumnSizes` 表示每个区间的列数,`returnColumnSizes` 表示合并后的区间数组。

在函数内部,首先检查输入的数组大小是否小于等于1,如果是,则直接返回输入数组,因为不需要合并。接着,按照区间的起始位置对数组进行排序。然后,遍历排序后的区间数组,逐个合并重叠的区间,将合并后的区间加入结果数组。最后,返回结果数组。


void printIntervals(int** intervals, int size, int* columnSizes) {
    for (int i = 0; i < size; i++) {
        printf("[%d, %d] ", intervals[i][0], intervals[i][1]);
    }
    printf("\n");
}

这个函数用于打印区间数组,接收一个二维整数数组 `intervals`、数组的大小 `size`,以及每个区间的列数数组 `columnSizes`。在循环中,它逐个打印每个区间的起始和结束位置。

希望这个分析对您理解这段代码有所帮助。如果有其他问题,请随时问!

完整代码

#include <stdio.h>
#include <stdlib.h>

// 比较函数用于排序
int compare(const void* a, const void* b) {
    return ((int*)a)[0] - ((int*)b)[0];
}

// 合并重叠区间的函数
int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes) {
    if (intervalsSize <= 1) {
        *returnSize = intervalsSize;
        *returnColumnSizes = intervalsColSize;
        return intervals;
    }

    // 按照区间的起始位置进行排序
    qsort(intervals, intervalsSize, sizeof(int*), compare);

    // 创建结果数组
    int** result = (int**)malloc(intervalsSize * sizeof(int*));
    *returnColumnSizes = (int*)malloc(intervalsSize * sizeof(int));
    int i, j;
    *returnSize = 0;

    // 遍历排序后的区间数组,逐个合并重叠的区间
    for (i = 0; i < intervalsSize; i++) {
        int currentStart = intervals[i][0];
        int currentEnd = intervals[i][1];

        // 合并重叠区间
        while (i < intervalsSize - 1 && currentEnd >= intervals[i + 1][0]) {
            i++;
            currentEnd = (currentEnd > intervals[i][1]) ? currentEnd : intervals[i][1];
        }

        // 将合并后的区间加入结果数组
        result[*returnSize] = (int*)malloc(2 * sizeof(int));
        result[*returnSize][0] = currentStart;
        result[*returnSize][1] = currentEnd;
        (*returnColumnSizes)[*returnSize] = 2;
        (*returnSize)++;
    }

    return result;
}

// 打印区间数组
void printIntervals(int** intervals, int size, int* columnSizes) {
    for (int i = 0; i < size; i++) {
        printf("[%d, %d] ", intervals[i][0], intervals[i][1]);
    }
    printf("\n");
}

int main() {
    int intervals1[][2] = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};
    int size1 = sizeof(intervals1) / sizeof(intervals1[0]);
    int colSize1 = sizeof(intervals1[0]) / sizeof(int);

    int** result1;
    int returnSize1;
    int* returnColumnSizes1;
    result1 = merge((int**)intervals1, size1, &colSize1, &returnSize1, &returnColumnSizes1);

    printf("示例 1 输出: ");
    printIntervals(result1, returnSize1, returnColumnSizes1);

    // 释放内存
    for (int i = 0; i < returnSize1; i++) {
        free(result1[i]);
    }
    free(result1);
    free(returnColumnSizes1);

    int intervals2[][2] = {{1, 4}, {4, 5}};
    int size2 = sizeof(intervals2) / sizeof(intervals2[0]);
    int colSize2 = sizeof(intervals2[0]) / sizeof(int);

    int** result2;
    int returnSize2;
    int* returnColumnSizes2;
    result2 = merge((int**)intervals2, size2, &colSize2, &returnSize2, &returnColumnSizes2);

    printf("示例 2 输出: ");
    printIntervals(result2, returnSize2, returnColumnSizes2);

    // 释放内存
    for (int i = 0; i < returnSize2; i++) {
        free(result2[i]);
    }
    free(result2);
    free(returnColumnSizes2);

    return 0;
}

能力有限,有任何问题可以私聊博主哈!!!

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

科技新华脉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值