- 题目描述
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。 示例 1: 输入: [0,1,3] 输出: 2 示例 2: 输入: [0,1,2,3,4,5,6,7,9] 输出: 8
- 解法一:直观解法
则道题第一想到的就是先求(n+1)*n/2的和然后求list的和,相减则为缺失的数,时间复杂度O(N),空间复杂度O(1)
class Solution: def missingNumber(self, nums: List[int]) -> int: sum1 = sum(nums) sum2 = (len(nums) * (len(nums) + 1)) // 2 return sum2 - sum1
- 解法二:二分法
要是面试的时候用直观解法,那肯定凉了。首先没有用到题目list的递增有序的性质,再有时间复杂度O(N),面试官并不满意。
我们需要分析下这个list的性质:
1.在0~n-1区间递增有序:那么索引为i的位置对应的数的值一定等于这个数的索引值
2.在缺失的数后面,索引为i的位置对应的数的值一定等于这个数的索引值+1
利用以上性质,我们可以用二分法先将list分为左右两边,中值为m,假如m的索引恒等于nums[m],那么这个缺失的数在m右边,假如m的索引不等于nums[m],那么这个缺失的数在m左边,以此为约束缩小查找区间。
class Solution: ''' 二分法,充分利用递增性质 ''' def missingNumber(self, nums: List[int]) -> int: i =0 j = len(nums) -1 while i <= j: m = (i + j) // 2 if nums[m] == m: i = m + 1 else: j = m -1 return i