1.寻找数组的中心索引
给你一个整数数组 nums ,请计算数组的 中心下标 。
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
示例 1:
输入:nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
中心下标是 3 。
左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,
右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。
示例 2:
输入:nums = [1, 2, 3]
输出:-1
解释:
数组中不存在满足此条件的中心下标。
示例 3:
输入:nums = [2, 1, -1]
输出:0
解释:
中心下标是 0 。
左侧数之和 sum = 0 ,(下标 0 左侧不存在元素),
右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。
int pivotIndex(int* nums, int numsSize){
int leftsum = 0;
int rightsum = 0;
int sum = 0;
for(int f = 0;f<numsSize;f++){
sum+=nums[f];
}
for(int i = 0;i < numsSize;i++){
if(leftsum*2+nums[i] == sum){
return i;
}
leftsum+=nums[i];
}
return -1;
}
2.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 为 无重复元素 的 升序 排列数组
-104 <= target <= 104
int searchInsert(int* nums, int numsSize, int target){
int low=0, high=numsSize-1, mid;
while(low<=high)
{
mid = low+(high-low) / 2;
if(nums[mid]==target)
{
return mid;
}
else if (nums[mid]<target)
{
low = mid+1 ;
}
else if (nums[mid]>target)
{
high = mid-1 ;
}
}
if(nums[mid]<target)
return mid + 1;
else if (nums[mid]>target)
return mid ;
return -1;
}
3.合并区间
以数组 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 <= starti <= endi <= 104
相关标签
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int array_cmp_int(const void *_a,const void *_b){
int *a = *(int**)_a;
int *b = *(int**)_b;
return a[0] - b[0];
}
int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes){
if (intervalsSize == 1) {
*returnSize = 1;
return intervals;
}
qsort(intervals,intervalsSize,sizeof(int*),array_cmp_int);
int** result = (int**)malloc(sizeof(int*) * intervalsSize);
for (int i = 0; i < intervalsSize; i++) {
result[i] = (int*)malloc(sizeof(int) * 2);
}
*returnSize = 0;
int temp[2] = {intervals[0][0],intervals[0][1]};
for (int i = 1; i < intervalsSize; i++) {
if (intervals[i][0] <= temp[1]) { //如果遍历到的为重叠的区间,进行合并
temp[1] = fmax(temp[1],intervals[i][1]);
}
else { //不重叠
result[*returnSize][0] = temp[0];
result[*returnSize][1] = temp[1];
temp[0] = intervals[i][0];
temp[1] = intervals[i][1];
(*returnSize) += 1;
}
}
result[*returnSize][0] = temp[0];
result[*returnSize][1] = temp[1];
*returnSize += 1;
*returnColumnSizes = (int*)malloc(sizeof(int)*(*returnSize));
for (int i = 0; i < *returnSize; i++){
(*returnColumnSizes)[i] = 2;
}
return result;
}
在这个函数声明中,_a
和 _b
是参数,而不是参数的指针。
int array_cmp_int(const void *_a, const void *_b)
这是一个函数原型,其中_a
和 _b
是形式参数(也称为函数参数)。在函数调用时,实际的参数值将被传递给这两个参数。
这里使用了 const void*
类型作为参数类型,这是因为这个函数是用于比较两个元素的回调函数,在某些情况下可能需要比较不同类型的数据。
const void*
是一个表示指向任意类型的常量指针的特殊类型。它允许在函数内部使用指针的方式来比较数据,而无需知道具体的数据类型。在函数内部,你可以根据实际需要将 _a
和 _b
强制转换为适当的指针类型,以便进行比较。
总而言之,_a
和 _b
是函数中的参数,它们接收传递给函数的实际值,并且在函数内部可以对其进行解引用或转换等操作。
int *a = *(int**)_a;
首先,代码的目的是将传入的指针 _a
转换为 int*
类型的指针 a
。为了理解这行代码,我们需要从右往左进行解读。
(int**)_a
:将_a
强制转换为int**
类型的指针。这里的(int**)
是为了说明_a
是一个指向指针的指针。也就是说_a
是一个二级指针。*(int**)_a
:通过对指向指针的指针_a
进行解引用操作,将得到指针指向的内容。这里的*
是解引用操作符,它返回指针指向的值。int *a = *(int**)_a
:将解引用后的值赋给int*
类型的指针a
。这样,指针a
就指向了_a
指针指向的内容。
总结起来,此行代码的目的是将二级指针 _a
解引用,并将解引用后的值赋给 int*
类型的指针 a
。这样做是为了从 _a
中获取指向 int
类型的指针,并将其存储在 a
中以便后续使用
int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes)
这是一个函数声明,它定义了一个名为 merge
的函数,该函数接受多个参数并返回一个 int**
类型的指针。
下面是每个参数的解释:
-
int** intervals
:这是一个指向int
类型指针的指针,它表示一个存储整数区间的数组。每个整数区间由两个整数值组成,通常表示为intervals[i][0]
和intervals[i][1]
。这个参数接收存储整数区间的数组的地址。 -
int intervalsSize
:这是一个int
类型的值,表示存储整数区间的数组的大小(或元素个数)。 -
int* intervalsColSize
:这是一个指向int
类型的指针,表示存储整数区间的数组的每个子数组(整数区间)的列数。例如,如果每个整数区间由两个整数组成,那么它将指向一个包含两个元素的数组。该参数提供了关于每个整数区间的列数信息。 -
int* returnSize
:这是一个指向int
类型的指针,用于返回合并后的整数区间数组的大小(或元素个数)。 -
int** returnColumnSizes
:这是一个指向int*
类型的指针,用于返回合并后的整数区间数组的每个子数组(整数区间)的列数。它提供了关于每个合并后的整数区间的列数信息。
函数的返回类型为 int**
,它表示指向整数区间数组的指针。该函数将合并给定的整数区间数组,并返回合并后的整数区间数组。
qsort(intervals, intervalsSize, sizeof(int*), array_cmp_int);
这里通过调用qsort
函数对传入的区间数组进行排序。排序是根据区间的起始值进行的,这样可以方便后续的合并操作。
int** result = (int**) malloc(sizeof(int*) * intervalsSize);
for (int i = 0; i < intervalsSize; i++) {
result[i] = (int*) malloc(sizeof(int) * 2);
}
在进行合并之前,为结果数组result
分配内存。result
是一个二维数组,用于存储合并后的区间。
for (int i = 1; i < intervalsSize; i++) {
if (intervals[i][0] <= temp[1]) { //如果遍历到的为重叠的区间,进行合并
temp[1] = fmax(temp[1], intervals[i][1]);
} else { //不重叠
result[*returnSize][0] = temp[0];
result[*returnSize][1] = temp[1];
temp[0] = intervals[i][0];
temp[1] = intervals[i][1];
(*returnSize) += 1;
}
}
这段代码是一个循环,用于合并给定的整数区间数组。
代码逻辑如下:
- 在循环开始之前,我们假设
temp
是一个临时的整数区间,用于存储当前合并的区间。 - 循环从数组的第二个元素开始(
i = 1
),遍历整数区间数组。 - 如果当前遍历到的区间与
temp
区间重叠(即intervals[i][0]
小于等于temp[1]
),则更新temp[1]
,取两个区间结束位置的较大值,以确保合并后的区间覆盖范围更大。 - 如果当前遍历到的区间与
temp
区间不重叠,说明已经找到了一个新的不重叠区间,需要将当前的temp
区间添加到结果数组result
中,并更新temp
为当前遍历到的区间。 - 每次进入不重叠区间的分支时,将
(*returnSize)
(通过指针传递的变量)增加 1,以表示已经添加了一个合并后的区间。 - 循环结束后,最后一个合并后的区间仍然保存在
temp
中,所以需要将其添加到结果数组result
中。
请注意,这段代码片段只展示了合并逻辑的一部分,并且需要进一步组合其他代码来完成整个 merge
函数的实现。
returnSize和returnColumnSizes各指什么
returnSize
和 returnColumnSizes
是两个通过指针传递的参数,用于返回合并操作后的结果和相关信息。
-
returnSize
是一个指向int
类型的指针。在函数开始时,它的值表示合并后的区间数组的大小(即元素个数)。在函数执行过程中,每当合并一个区间,就会通过(*returnSize) += 1
将其增加 1。最终,returnSize
的值将是合并后的区间数组的实际大小。 -
returnColumnSizes
是一个指向int*
类型的指针。在函数内部,它会通过动态内存分配(使用malloc
)来为每个合并后的区间的子数组分配空间。具体而言,它会分配一个int
类型数组,用于存储每个子数组(合并后的区间)的列数。在函数结束时,returnColumnSizes
将指向这个动态分配的数组。
通过使用这两个参数,函数能够将合并后的结果和相关信息以指针的形式返回给调用者。调用者可以通过解引用这些指针来访问合并后的区间数组以及每个子数组的列数信息