前言:内容包括:题目,代码实现,大致思路,代码解读
目录
题目:
代码实现:
大致思路:
代码解读:
part 1
part 2
题目:
给定一个 无重复元素 的 有序 整数数组 nums 。
返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。
列表中的每个区间范围 [a,b] 应该按如下格式输出:
"a->b" ,如果 a != b
"a" ,如果 a == b
示例 1:
输入:nums = [0,1,2,4,5,7]
输出:["0->2","4->5","7"]
解释:区间范围是:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"
示例 2:
输入:nums = [0,2,3,4,6,8,9]
输出:["0","2->4","6","8->9"]
解释:区间范围是:
[0,0] --> "0"
[2,4] --> "2->4"
[6,6] --> "6"
[8,9] --> "8->9"
提示:
0 <= nums.length <= 20
-231 <= nums[i] <= 231 - 1
nums 中的所有值都 互不相同
nums 按升序排列
代码实现:
char** summaryRanges(int* nums, int numsSize, int* returnSize)
{
char** ret = (char**)calloc(numsSize, sizeof(char*));
int i = 0;
for (i = 0; i < numsSize; i++)
{
ret[i] = (char*)calloc(25, sizeof(char));
}
int left = 0;
int index = 0;
for (i = 0; i < numsSize; i++)
{
left = i;
while (i < numsSize - 1 && nums[i] + 1 == nums[i + 1])
{
i++;
}
if (left == i)
{
sprintf(ret[index++], "%d", nums[i]);
}
else
{
sprintf(ret[index++], "%d->%d", nums[left], nums[i]);
}
}
*returnSize = index;
return ret;
}
大致思路:
区间的划分:连续的数字成为一个区间
比如:0,1,2,4,5,7
区间的划分为:0~2 4~5 7
1 遍历整个数组: 每次先用left存储左区间数字的下标,当满足前一个元素(下标是i)+1 = 后一个元素(下标是i+1)时,不断跳过这个下标为i的元素,当不满足条件结束循环时,i就是右区间的下标
2 若是区间仅有1个数值(left==i)即区间的左边界值的下标和右边界值的下标相等,则直接将此数值转成字符串即可
若是区间的数值>1,则将一个区间左边界上的数值(left为其下标)和右边界上的数值(i为其下标)按照:数值->数值 的形式转成字符串
下面介绍一个能将数据转成字符串形式的函数:sprintf 将格式化数据写入字符串
语法:
int sprintf ( char * str, const char * format, ... );
终止空字符会自动追加到内容之后
代码解读:
part 1
char** ret = (char**)calloc(numsSize, sizeof(char*));
int i = 0;
for (i = 0; i < numsSize; i++)
{
ret[i] = (char*)calloc(25, sizeof(char));
}
calloc开辟一块numsSize大小的空间,每个空间的元素类型是char*类型,即字符数组的数组名
为开辟好的numsSize个空间存入一个字符数组的数组名,代表着一个字符串的首元素的地址
这个字符串的大小需要足够大,我们注意到nums[i] <= 2^31-1
即nums中的数字最大是10位数,添上负号存入字符数组中可以算作11个字符,不要忘记字符数组中要有一个位置留给sprintf自动追加的'\0'哦!
part 2
int left = 0;
int index = 0;
for (i = 0; i < numsSize; i++)
{
left = i;
while (i < numsSize - 1 && nums[i] + 1 == nums[i + 1])
{
i++;
}
if (left == i)//区间中只有一个数字
{
sprintf(ret[index++], "%d", nums[i]);//将数字写入字符数组中
}
else
{
sprintf(ret[index++], "%d->%d", nums[left], nums[i]);
}
}
*returnSize = index;
return ret;
遍历整个数组:
left存入一个区间左边界数值的下标
当下标为i的元素+1 = 下标为i+1的元素时,不断跳过这个元素
注意:
1 需要注意访问越界的问题,i只要遍历到数组倒数第二个元素的位置就好,因为倒数第二个元素的后一个元素就是数组的最后一个元素,若是i遍历到数组最后一个元素的位置,则i+1的位置不是数组的空间,属于非法访问
所以i<numsSize-1
2
while (i < numsSize - 1 && nums[i] + 1 == nums[i + 1])
条件不能颠倒位置,若是:
while (nums[i] + 1 == nums[i + 1] && i < numsSize - 1 )
会出现:在已经访问越界的情况下去判断是否越界文章来源:https://www.toymoban.com/news/detail-413713.html
所以我们要防患于未然,先判断访问是否越界文章来源地址https://www.toymoban.com/news/detail-413713.html
到了这里,关于leetcode:汇总区间(详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!