当前位置:网站首页>LeetCode56:合并区间 C语言解法,注解详细 一看就懂!
LeetCode56:合并区间 C语言解法,注解详细 一看就懂!
2022-08-09 09:29:00 【农场主er】
思路分析:
1. 首先进行给定区间的排序:
题目中我选择了快速排序,需要注意的是要根据二维数组每行的首元素大小进行排序,并且每次需同时交换两个元素。
2. 遍历排序好的二维数组:
每次需要比较intervals[i][1]和intervals[i+1][0],如果后者大,证明区间不重叠,此时不做特殊处理,否则合并区间。
代码实现
关于题目中给的形参:
我个人认为int* intervalsColSize是没有必要的,因为intervals的行数由intervalSize给定,列数固定为2。
#include <stdio.h>
#include <stdlib.h>
//找到划分区间时所用元素位置
int Partition(int** intervals, int low, int high) {
int pivot = intervals[low][0];
int secpivot = intervals[low][1];
while (low < high) {
while (low < high&&intervals[high][0] >= pivot)
high--;
intervals[low][0] = intervals[high][0];
intervals[low][1] = intervals[high][1];
while (low < high&&intervals[low][0] <= pivot)
low++;
intervals[high][0] = intervals[low][0];
intervals[high][1] = intervals[low][1];
}
intervals[low][0] = pivot;
intervals[low][1] = secpivot;
return low;
}
//快速排序
void QuickSort(int** intervals, int low, int high) {
if (low < high) {
int pivotpos = Partition(intervals, low, high);
QuickSort(intervals, low, pivotpos);
QuickSort(intervals, pivotpos+1, high);
}
}
//合并区间
int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes) {
QuickSort(intervals, 0, intervalsSize - 1);
//申请内存,此时不确定合并之后的数组大小,只能按照intervalSize进行申请
int **target = (int **)malloc(sizeof(int *)*intervalsSize);
*returnColumnSizes = (int *)malloc(sizeof(int) * intervalsSize);
//引入两个中间变量,一来表述方便,二来起到记忆比较元素的效果
int start = 0, end = 0;
*returnSize = 0;
//遍历需要合并的数组
for (int i = 0; i < intervalsSize; i++) {
start = intervals[i][0];
end = intervals[i][1];
//这里一定要把i < intervalsSize - 1写到前面,否则将会出错!
while (i < intervalsSize - 1 && intervals[i + 1][0] <= end) {
end = intervals[i + 1][1] > end ? intervals[i + 1][1] : end;
i++;
}
//动态内存分配,避免内存浪费
target[*returnSize] = (int *)malloc(sizeof(int) * 2);
//注意前面的括号,下标引用的优先级高于间接访问
(*returnColumnSizes)[*returnSize] = 2;
//将比较好的元素加入到目标数组中
target[*returnSize][0] = start;
target[*returnSize][1] = end;
(*returnSize)++;
}
//减小已分配的内存大小,因为刚开始申请的内存大于等于修改后的内存
target=(int **)realloc(target,sizeof(int *)*(*returnSize));
return target;
}
复杂度分析:
时间复杂度:O ( n log n )
主要来源于排序的复杂与否空间复杂度:O ( n )
我的空间复杂度打败了100%的提交解法,有点骄傲,嘻嘻。
避免bug的几个注意点:
- 内存分配的几个地方,注意返回指针的类型转换;
- for循环遍历数组时,while语句一定要对i-1的大小进行限定,且写在前面,即先判断,避免判断到intervals[i + 1][0] <= end时下标超出界限;
- 最后调用realloc()函数进行申请内存的修改可减小程序的占用空间。
写在最后:
这道题花了我整整一天…起初用Java写,很少的代码就解决了问题,但是C语言涉及到指针及内存,很容易出错,而且排序算法需要自己写。好在,我熬了过来!最后提交成功时已经是凌晨一点,非常的兴奋,这恐怕就是程序的魅力了吧!
(如有问题,欢迎评论区交流。)
边栏推荐
- 常用功能测试的检查点与用例设计思路
- 用户设备IP三者绑定自动上号
- Cisco common basic configuration of common commands
- 接口设计
- The div simulates the textarea text box, the height of the input text is adaptive, and the word count and limit are implemented
- 4. Character stream
- 软件测试流程包括哪些内容?测试方法有哪些?
- A little experience sharing about passing the CISSP exam at one time
- 白盒测试的概念、目的是什么?及主要方法有哪些?
- 3.List interface and implementation class
猜你喜欢
随机推荐
迭代
.equals ==
自动化测试简历编写应该注意哪方面?有哪些技巧?
Sweet alert
3. Practice the Thread
MySQL Leak Detection and Filling (2) Sorting and Retrieval, Filtering Data, Fuzzy Query, Regular Expression
Go-goroutine 的那些事
接口测试的概念、目的、流程、测试方法有哪些?
3.List接口与实现类
常用的一些制表符号
MySQL索引、视图、设计三范式,通俗易懂,不可错过!
latex中复杂公式换行等号对齐
A first look at the code to start, Go lang1.18 introductory refining tutorial, from Bai Ding to Hongru, the first time to run the golang program EP01
一篇文章让你彻底搞懂关于性能测试常见术语的定义
银联最新测试工程师笔试题目,你能得多少分?
map去重代码实现
nacos从下载到安装集群的
8. Recursively traverse and delete cases
你一定要看的安装及卸载测试用例的步骤及方法总结
unix环境编程学习-多线程







