剑指 Offer 53 - II. 0~n-1中缺失的数字

题目:
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

题解思路:

方法一:数组排序法
1…数组已经是排序,遍历数组的元素,元素值不等于下标值,则数组中缺失的数字就是它。

函数代码:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        //如果数组没有排序,就排序数组,,题目中数组元素递增
        //sort(nums.begin(),nums.end())
        
        int i;
        for(i=0; i<nums.size(); i++)
        {
            if(i != nums[i])
            {
               break ;
            }
        }
        return i ;
    }
};

方法二:数组求和作差法
1.在不缺失数字的情况下,求出总数sum
2.用sum减去数组中元素的值,遍历数组即可。

函数代码:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        //n+1是一共元素的个数(包括0),从0到n,
      
        int sum=(0+n)*(n+1)/2;
        for(int i=0;i<n;i++)
        {
            sum=sum-nums[i];
        }
        return sum;
    }
};

函数代码:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        //元素0不计入数组长度,也不计入sum
        //所以1到n长度为n,累加求起始元素是1不是0
        int sum=(1+n)*n/2;
        for(int i=0;i<n;i++)
        {
            sum=sum-nums[i];
        }
        return sum;
    }
};

方法三:二分查找
1.让left=0,right=nums.size()-1,这就是取闭区间(while(left<=right))
2.让mid=(left+right)/2,判断nums[mid]是否相等于下标mid,如果相等,则表明前面都是有序,不缺失数字的,在右边查找,即left=mid+1;如果不等,在左边查找,即right=mid-1
3.当不满足循环判断条件时(left<=right)时,退出循环,返回left

函数代码:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int left=0;
        int right=nums.size()-1;
        while(left<=right)
        {
            //防止数据溢出
            int mid=left+(right-left)/2;
            if(nums[mid]==mid)
            {
                left=mid+1;
            }
            else
            {
                right=mid-1;
            }
        }
        return left;
    }
};

方法:二分查找,左闭右开
1.因为left=0,right=nums.size();循环条件是while(left<right)终止条件肯定是 left = right
2.在进行划分区间时,左边left已经判断了该值,所以是mid + 1。右边是我们的哨兵元素所以是mid,mid-1就会忽略掉一个元素。因为我们是缺少某个元素,所以不可能出现nums[i] < i的情况。
3.终止条件有一个位置出现值大于我们的数组下标,比如题目的8的位置是9,这时我们的left不断右逼到指向8,再做一次判断right也指向了8循环终止,所以我们返回的left和right都可以。

函数代码:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int left=0;
        int right=nums.size();
        while(left<right)
        {
            //防止数据溢出
            int mid=left+(right-left)/2;
            if(nums[mid]==mid)
            {
                left=mid+1;
            }
            else if(nums[mid]>mid)
            {
                right=mid;
            }
        }
        return left;
    }
};

方法四:hash法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值