以数组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;
}
能力有限,有任何问题可以私聊博主哈!!!