问题描述
给定一个排序的整数数组 nums ,其中元素的范围在 闭区间 [lower, upper] 当中,返回不包含在数组中的缺失区间。
示例:
输入: nums = [0, 1, 3, 50, 75], lower = 0 和 upper = 99,
输出: [“2”, “4->49”, “51->74”, “76->99”]
解题思路
这道题思路比较简单,就是比较相邻的数的大小关系,判断输出样式。
- 若nums[i]与下一个数差为2,则输出nums[i]+1
- 若nums[i]与下一个数差大于2,则输出nums[i]+1 “->” nums[i+1]-1
- 对upper与lower的判断,2个方案:
- 对upper+1,lower-1,作为元素加入容器,按照上面的方式执行(简化了问题,但注意upper+1,lower-1可能会计算溢出)
- 与上面的情况分开,也就是按照不同情况处理,第一个元素与lower比较;最后一个元素与upper比较(通过设置条件,可以避免计算导致的溢出)
溢出举例:
[-2147483648,2147483647]
-2147483648
2147483647
第一种方案(推荐,int->long long)
直接将long long 型加入int型的容器,似乎很麻烦(没深究)。感觉下面这种方式很有技巧
class Solution {
public:
vector<string> findMissingRanges(vector<int> &nums, int lower, int upper) {
vector<string> ans;
int size = nums.size();
long long left = (long long)lower - 1;
long long judge;
for (int i = 0; i < size; ++i) {
judge = nums[i] - left;
if (judge == 2) {
ans.push_back(to_string(nums[i] - 1));
} else if (judge > 2) {
ans.push_back(to_string(left + 1) + "->" + to_string(nums[i] - 1));
}
left = nums[i];
}
judge = upper - left;
if (judge == 1) {
ans.push_back(to_string(upper));
} else if (judge > 1) {
ans.push_back(to_string(left + 1) + "->" + to_string(upper));
}
return ans;
}
};
第二种方案(没有转换变量类型):
class Solution {
public:
vector<string> findMissingRanges(vector<int>& nums, int lower, int upper) {
sort(nums.begin(),nums.end(),less<int>());
vector<string> ans;
int len=nums.size();
string s;
if(len==0&&upper==lower) //容器为空的情况
{
ans.push_back(to_string(upper));
return ans;
}
else if(len==0&&upper>lower)
{
ans.push_back(to_string(lower)+"->"+to_string(upper));
return ans;
}
if(nums[0]==lower) ;//nums[0]不可能小于lower,若lower为最大值,nums[0]必是最大值
else if(nums[0]==lower+1)
//唯一的计算:lower+1,
//但lower为int上限的最大值已经在上一行排除了
//(巧改nums[0]-lower==1)
ans.push_back(to_string(lower));
else if(nums[0]>lower+1)
ans.push_back(to_string(lower)+"->"+to_string(nums[0]-1));
for(int i=0;i<len-1;i++)
{
if(nums[i+1]==nums[i]);
else if(nums[i+1]-2==nums[i])
ans.push_back(to_string(nums[i]+1));
else if(nums[i+1]-2>nums[i])
ans.push_back(to_string(nums[i]+1)+"->"+to_string(nums[i+1]-1));
}
if(upper==nums[len-1]) ;
else if(upper-1==nums[len-1])
ans.push_back(to_string(upper));
else if(upper-1>nums[len-1])
ans.push_back(to_string(nums[len-1]+1)+"->"+to_string(upper));
return ans;
}
};
回顾知识点:
- 将int转化为string型(C++11新特性):to_string()函数
- 对容器进行排序:sort(vec.begin(),vec.end(),less())
具体用法见:博客地址 - 对容器的重复元素删除(留下一个)技巧:
vec.erase(unique(vec.begin(), vec.end()), vec.end());
- 如果不对可能溢出的变量变换类型(int->long long),通过避免对溢出变量的计算(加判断条件等等),可以避免溢出