首页 查找消失的数字
文章
取消

查找消失的数字

问题

一个无序数列存储了 0~n 这 n+1 个数字,去除一个。如何查找这个丢失的数字?

解法

求差

用未去除的数列和减去现在的数列和,即为缺失的数字。

1
2
def get_missing_num(nums):
    return sum([x for x in range(len(nums) + 1)]) - sum(nums)

这种方法,其实遍历了2次。

可以使用等差数列求和的方法求前 n 项的和,以减少遍历的次数。

对于等差数列 \({a_1},{a_2},{a_3} \cdots {a_n}\),其中

\[{a_n}={a_1}+(n-1) \times d\]

等差数列的和:

\[{S_n}=n{a_1}+ \frac{n(n-1)}{2}d\]

\[{S_n}=\frac{n({a_1}+{a_n})}{2}\]

方法如下:

1
2
def get_missing_num(nums):
    return int(len(nums) * (0 + len(nums) + 1) / 2) - sum(nums)

位运算

可以利用二进制的异或运算消掉没有去除的数字,那么首先要把每个数字都复制一个,再用异或消除。

参考:二进制的异或运算

1
2
3
4
5
6
from functools import reduce


def get_missing_num(nums):
    tmp_nums = nums + [x for x in range(len(nums) + 1)]
    return reduce(lambda x, y: x ^ y, tmp_nums)

上面的这种方法,也遍历了2次,可以优化为以下方法:

1
2
3
4
5
6
7
8
def get_missing_num(nums):
    # 先初始化为有序数列中的首位,即 0
    result = 0
    for i in range(len(nums)):
        # 将数列中的每位与有序数列中的每位(从 1 到 n)异或运算
        result ^= (i + 1) ^ nums[i]
    # 最终的结果即为缺失的数字
    return result
本文由作者按照 CC BY 4.0 进行授权