53-02 0到n-1中缺失的数字

题目

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

AcWing OJ

C语言题解

若数组没有缺失,则每个数字和它的下标都相等。然而,现在数组有缺失,说明从缺失的那个数开始,后面的数字都比它的下标大1。因此找出第一个数值和下标不相等的数,那么,它的下标就是缺失的那个数。
数组可看成两部分,前半段数值和下标相等,后半段数值和下标不相等,且数组是有序的。所以,使用二分查找:
若中间数的值和下标相等,则在后半段继续寻找;
若中间数的值和下标不相等,且中间数的前一个元素的值等于它的下标相等,那么这个中间数就是第一个值和下标不相等的数,它的下标就是缺失的那个数,否则继续在前半段寻找。

int GetMissingNumber(const int* numbers, int length)
{
	if (numbers == nullptr || length <= 0)
		return -1;

	int left = 0;
	int right = length - 1;

	while (left <= right)
	{
		int middle = (right + left) >> 1;
		// 中间的数与索引不相等
		if (numbers[middle] != middle)
		{
			// 中间位置前一个还是索引数字对应,那么说明正是中间位置开始索引数字不对应了
			if (middle == 0 || numbers[middle - 1] == middle - 1)
				return middle;

			// 缩小查找范围,在中间数字前面继续搜索
			right = middle - 1;
		}
		else
			left = middle + 1;
	}

	if (left == length)
		return length;

	// 无效的输入,比如数组不是按要求排序的,
	// 或者有数字不在0到n-1范围之内
	return -1;
}

C++ 题解

方法一

nums数组中的数的和 sum = 0 + 1 + … + (miss-1) + (miss+1) + …+(n+1)
n*(n+1)/2 = 0 + 1 + … + (miss-1) + miss + (miss+1) + …+(n+1) = sum + miss
取二者之差即为所求:

class Solution {
public:
    int getMissingNumber(vector<int>& nums) {
        int n=nums.size(),sum=0;
        for(auto &x:nums)
            sum += x;
        return n*(n+1)/2 - sum;
    }
};

方法二

二分查找

class Solution {
public:
    int getMissingNumber(vector<int>& nums) {
        int left=0,right=nums.size()-1;
        // 如果数组的长度小于1,则返回0
        if(right<0)
            return 0;
        // 如果数组中没有缺失的元素,那么返回right+1
        if(nums[right] == right)
            return right+1;
        int mid = (left + right) >> 1;
        
        while(left < right)
        {
            mid = left + right >> 1;
            // 如果中间的数字与索引相等,说明缺失的元素在中间元素的后边
            if (nums[mid] == mid)
                left = mid + 1;
            // 否则的话,缺失的数字一定在中间元素的前边
            else 
                right=mid;
        }
        
        
        return nums[right] -1;
    }
};

python 题解

方法一

class Solution(object):
    def getMissingNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n,sum = len(nums),0
        
        for i in nums:
            sum += i
        
        return n*(n+1)/2 - sum

方法二

二分查找:

class Solution(object):
    def getMissingNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        left,right = 0,len(nums)-1
        
        if right<0:
            return 0
        
        if nums[right] == right:
            return right + 1
        
        mid = (left+right)//2
        while left < right:
            mid = (left+right)//2
            if nums[mid] == mid:
                left = mid + 1
            else: 
                right = mid
        
        return nums[right] - 1
posted @ 2019-03-17 09:16  youngliu91  阅读(214)  评论(0)    收藏  举报