缺失的区间-处理溢出

问题描述

给定一个排序的整数数组 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个方案:
    1. 对upper+1,lower-1,作为元素加入容器,按照上面的方式执行(简化了问题,但注意upper+1,lower-1可能会计算溢出)
    2. 与上面的情况分开,也就是按照不同情况处理,第一个元素与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),通过避免对溢出变量的计算(加判断条件等等),可以避免溢出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值