53-02 0到n-1中缺失的数字
题目
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0到n-1之内。在范围0到n-1的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
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

浙公网安备 33010602011771号