算法学习(十三)一堆数据中找到丢失数字问题

题目描述:
每个机器都有一个标号Id,每个id数据保存两个备份,如果一台机器死机,就会丢失一个备份,如果得到一个数据文件Id的列表,是否能够快速找到这个仅出现一次的Id?
分析:
其实就是海量数据中有一个数据是只出现一次的,其他都是出现两次,找到那个出现一次的数据。
解法一:
这种记录出现次数的问题,最先想到的当然就是伴随数组,遍历列表,数组元素为数据出现次数,数组下标可以是标号id,那个次数为1的Id就是我们要找的结果,时间复杂度为O(N),空间复杂度为O(N)。但是面对海量数据,这个空间复杂度也是够呛。
解法二:
能不能节省数据存储空间呢?这个题的特点就是我们要找的是只出现一次的,如果已经出现了两次,那肯定不是我们要找的,于是,如果次数为2,我们就可以直接丢弃了。使用哈希表,遇到一个元素加入到表中,次数加一,如果次数为2,就删除对应的Id,最后剩下的id就是我们要找的,空间复杂度最好的情况下为O(1),不过最坏的也是O(N)
解法三:
我们发现相同数据出现的是偶数次,最后只剩下一个奇数次的数据,可以考虑使用位运算中的异或(^)。注意异或运算满足交换律和结合律,其他出现两次的Id异或完都是0。我们可以遍历列表,然后依次加入异或运算,最后剩下的就是出现一次的id。
时间复杂度为O(N),空间复杂度为O(1)。

如果是两台机器死机呢?我们能否找到故障机器?

分析:
就是有两个Id只出现了一次,设为A和B。如果使用异或方案,最后剩下的就是A^B,如果A和B相同,就是一台机器的两个备份都丢失了,那么最后A^B为0。如果A和B不相同,则A ^B 不为0,我们可以找到A^B中某一位为1的位,则A和B中只用其中一个对应位上为1,我们可以以此位为判断依据。将Id分为两类,一类此位为1,一类为0,然后分别使用异或的方法,每一类中可以得到一个结果,分别为A和B。
再讨论A和B相同的问题,我们可以保存所有的id的求和,然后再计算剩下的id之和,然后将原来的总和减去当前的id和,得到的是死机机器id的和 A+ B,如果相等,直接(A+B)/2,得到死机的Id 号。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值