寻找遗失的整数 (Finding The Missing Integer)

问题描述: 大小为 n 的数组 A 中包含了 [0,n] 中的除了 x 的所有其它整数。找出 x。

问题很简单,如果不加约束条件的话。

约束一: (in place) 只用 O(1) 的额外空间,并要求 O(n) 时间。

约束二: 假定A 的元素都用二进制表示。我们不能直接访问整个元素。允许的操作是 fetch(i,j),它返回第 i 个元素的第 j 个 bit,所用时间为O(1)。用 O(n) 次 fecth 操作求出 x。

先来看约束一。感觉问题提得比较平凡,也许只是为了和约束二进行对比吧。用初中数学知识就可以解决了:把所有元素加起来,然后和 0 到 n 所有整数之和做比较就能知道哪个数字缺失了。

在约束二的情况下,上述的方法就不行了,因为要求和就得把所有元素的所有位取出来,这样的 fetch 次数是 O(nlogn)。由于这些数是分布中[0,n] 之间,且各不相同,那么,偶数和奇数的个数相差不过2个。如果我们能知道 x 的奇偶性,就能排除掉一半了。令 T(n) 表示求解规模为 n 的问题所有的 fetch 次数,假设通过 f(n) 次 fetch 操作可以排除掉一半,则 T(n) = T(n/2) + f(n)。根据 Master 定理,若 f(n),则 T(n) = O(n)。很显然,把所有数的最后一位取下来,再利用 n 的奇偶性就可以判定 x 的奇偶性,所需 fetch 次数为 n。可以证明,排除掉一半之后,在剩下来的另一半中,倒数第二个 bit 的 0 和 1 的个数之差也不会超过 2,因此,子问题 T(n/2) 也可以用同样的方法求解。解毕。

这道题没什么难的地方,有趣的是,在每个子问题中,我们都把该子问题的最后一位全部取到了。这样初一看,似乎要用 O(nlogn) 的 fetch。然后,由于折半的效应,事实上仍然总的只用了 O(n) 次 fetch 操作。试比较一下快速排序和用分治的方法选取第 i 个最小的元素,快排的平均时间为 O(nlogn),而后一个问题只要 O(n)。这是因为,快排需要对两个子问题分别求解,而后一个问题,平均情况下我们可以排除掉一半元素,只求解一个子问题,因此为 O(n)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值