编程之美 1.5快速找出故障机器
问题:假设一台机器仅保存一个标号为ID的记录,每份数据有两个备份,分别存储到两台机器中。
1.在某个时间,如果得到一个数据文件ID列表,能否快速找出仅出现一次的ID?
2.如果已经知道只有一台机器死机呢?如果有两台机器死机呢?
(假设同一数据两个备份不会同时丢失)
解法一:
遍历ID列表,记录各ID的出现次数。 空间复杂度:O(N) 时间复杂度:O(N)
解法二:
解法一的改进,利用变长数组,如果出现2次删除这个ID,空间复杂度最好时O(1),最坏时O(N)
解法三:
异或运算XOR
对于第一问,遍历完ID列表得到的运算结果即为仅出现一次的ID;
对于第二问,若有两台机器死机且ID不相同,设它们为A与B,异或运算最终得出的是result=A xor B的值,无法确定A与B的值。显然这result中某一位为1时,A与B中有且仅有一个数在这一位上也为1。这样我们就可以将所有的ID分为两类,一类在这位上为1,另一类这位上为0。每一类分别含A与B中的一个,只需分别对这两类ID做异或运算即可。
例:11 8 11 7 10 12 10 12 result=15
A类(第一位为1):11 11 7
B类(第二位为0):8 10 12 10 12
这解法的缺陷是若两台机器死机ID相同就无法检测出来。
解法四:
避免了解法三的缺陷,利用数学中“不变量”的概念,例如预先保存所有ID之和与所有ID之积。
对于两台机器死机的话,就可以列出如下方程:
x+y=a
xy=b
不过实现上可能会有问题,就是大整数乘法造成算术溢出,可以尝试通过采用平方和来解决。