参考内容:万门大学.数据结构与算法进阶(python版本)哔哩哔哩学习视频
一、题目内容
找到丢失的数字:现在你手上有n-1个数字,这些数字的范围是[1,n],且这n-1个数字中没有重复的数字。有上述条件可知:你手上的数字缺了一个。请编写一段高效的找到缺失数字的代码。
二、题目分析
此题是一道比较老的数据结构与算法考题,首先,在解答该题时,要进行一些题目的分析,题目分析我们主要做些什么呢?
要弄清楚。这n-1个数字是排好序了的吗?
该题有哪些解法思路呢?
要通过分析时间复杂度和空间复杂度说明那种解法最优呢?
最优解法的代码如何实现?
能不能写出测试用例呢?
三、题目解答
1. 排序后使用二分法查找
list.sort()
算法时间复杂度 = 排序的时间复杂度() + 二分查找的时间复杂度(log)
2. 排序后使用线性查找
算法时间复杂度 = 排序的时间复杂度() + 二分查找的时间复杂度(n)
3. 求和作差法
思路:sum = 1+2+3+....+n = n(n-1)/2sum = sum - list[i]num = sum //最后作差剩下的数
def FindMissingNumber(nums):s = 0for i in range(0,nums[-1] + 1):s = s + ifor n in nums:s = s - nreturn sprint(FindMissingNumber([1,3,5,6,4,7]))
4. 计数排序
有n个抽屉,每个抽屉里面放一个数,最后有空的抽屉就应该装缺失的数。
def FindMissingNumber(nums):chouti = [ 0 for i in range(len(nums)+1)] # n(列表长度加1)个抽屉里面全为空for n in nums:chouti[ n-1] = 1 # 将数放到对应的抽屉,并标记该抽屉也有数return chouti.index(0)+1 # 获取空元素的下标并加1,因为下标是从0开始的print(FindMissingNumber([1,3,5,6,4,7]))
5. 排序后异或求解
异或的知识:
相同为0, 不同为10 ^ 0 = 0 ;0 ^ 1 = 1 ;1 ^ 0 = 1 ;1 ^ 1 = 0 ;8 ^ 3 = 1011100000111011A ^ A = 0A ^ 0 = A10101010= 00010100000= 1010A ^ B ^ C ^ D = 0 //表示二进制数最后一位1的个数为偶数
有了上面的思想, 我们可以将n-1 个数a```` , a```` .... ,a```` 1, 2 , .... , n
进行逐位异或,最后选出异或结果不为0的数。
def FindMissingNumber(nums):new_nums = sorted(nums)n = len(new_nums)for i in range(1,n+2):if i^ new_nums[i-1] != 0:return ibreakprint(FindMissingNumber([1,3,5,6,4,7]))
