https://leetcode-cn.com/problems/missing-number/
Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. For example, Given nums = [0, 1, 3] return 2
Follow up: Could you implement a solution using only O(1) extra space complexity and O(n) runtime complexity?
这道题给我们n个数字,是0到n之间的数但是有一个数字去掉了,让我们寻找这个数字,要求时间复杂度O(n)和空间复杂度O(1)。
解法1:
那么最直观的一个方法是用等差数列的求和公式求出0到n之间所有的数字之和,然后再遍历数组算出给定数字的累积和,然后做减法,差值就是丢失的那个数字,参见代码如下:
但是这种解法存在空间溢出的问题
class Solution:
def missingNumber(self, nums: List[int]) -> int:
sum = 0
for i in nums:
sum = sum+i
length = len(nums)
mis = (0+length)*(length+1)/2-sum
return int(mis)
解法2:
使用位操作Bit Manipulation来解的,用到了异或操作的特性,^代表异或。异或虽然是二进制计算,但从大的理解上可以理解为如果数字n^n=0; n^m为一串二进制,其中有一位为1;0^n = n。所以假设array为[1,2,3],消失的数字为4,那么让整串数字[1,2,3,4]与[1,2,3]这七个数字进行异或操作,相同的抵消为0,那么只剩0^4 = 4,消失的数字为4。
class Solution:
def missingNumber(self, nums: List[int]) -> int:
res = 0
for i in range(len(nums)):
res ^= i^nums[i]
res ^= len(nums)
return res
解法3:
使用binary search O(logn)
index 0,1,2,3,4
nums0,2,3,4
如果mid==nums[mid], 那么left = left+1;如果mid<nums[mid],那么right = mid。最后left==right跳出循环,判断是否缺少最大值的可能性。
class Solution:
def missingNumber(self, nums: List[int]) -> int:
left, right = 0, len(nums)-1
nums.sort()
while(left<right):
mid = (left+right)//2
if mid== nums[mid]:
left = mid+1
elif mid<nums[mid]:
right = mid
if right == nums[right]:
return right +1
return right
类似的有消失两次的数字,原题https://leetcode-cn.com/problems/missing-two-lcci/
给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗?以任意顺序返回这两个数字均可。
与上一个问题相同,得到的res就是消失的两个数字n,m的异或,res的二进制一定有一个1,
可以采用两种方式求div为1的位置。
class Solution:
def missingTwo(self, nums: List[int]) -> List[int]:
res = 0
for i in range(len(nums)):
res ^= (i+1)^nums[i]
res ^= (len(nums)+1)^(len(nums)+2)
#求res的右边第一个1
方法1:
div = 1
while (div&res == 0):
div<<=1
方法2:
# div = res&-res
#开始将list分成两类
a, b = 0,0
for ele in nums:
if div&ele:
a ^= ele
else:
b ^= ele
for i in range(1, len(nums)+3):
if div&i:
a ^= i
else:
b ^= i
return a,b
相似题目:
剑指 Offer 56 - I. 数组中数字出现的次数, https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/
137. 只出现一次的数字 II, https://leetcode-cn.com/problems/single-number-ii/
136. 只出现一次的数字, https://leetcode-cn.com/problems/single-number/
260. 只出现一次的数字 III, https://leetcode-cn.com/problems/single-number-iii/