《编程之美》蛮有意思的

“快速找出机器故障”直接讨论这样的数学问题:

 

1、一个庞大的数据列表中,每个数据都有两个备份(两个ID相同),现在某份数据丢失了一个备份,请把这个丢失的ID找出来。

 

如果用一个数组保存每个ID出现的次数去遍历列表,这样时间复杂度和空间复杂度都为O(n)(如果数据太多不建议使用)

 

哈希表:

用哈希表。遍历列表,如果当前数据还没出现过就放到哈希表里,如果哈希表中已经存在此数据,就删除它。最后哈希表中剩余的数就是丢失数据。这样空间复杂度最好情况下可以达到O(1),最坏是O(n)。

 

抑或法:

遍历列表,每个数抑或。这样最后剩余的数就是丢失数据,这样空间复杂度已经降到O(1)。

 

不变量法:

如果所有的数一开始就是一个“不变量”,是一个固定值,那他们的和也是固定的。

现在丢失了一个数据,我们可以未丢失之前的和减去丢失后的和,这样就得到了丢失的数(推荐)。

 

 

2、每个数据都有两个备份(两个ID相同),现在丢失了两个数据,丢失的两个数据不为同一ID。

 

问题同样可以想象成一个数组中丢了两个不同的数。

 

抑或法:

同样可以使用抑或法,不过第一次我们无法从抑或的结果直接得出两个具体的数。

这个抑或的结果,某个位如果为1,则有一个数那个位一定为1,另一个数那个位一定为0。

然后兵分两路抑或,就能得出结果。

 

不变量法:

同样我们用和相减后可以知道丢失的两个数的和,如果我们能再构造一个关于这两个数的方程比如他们的乘积或者平方和(推荐,因为乘积数字太大)。即可求出两个数。

 

 

3、每个数据都有两个备份(两个ID相同),现在丢失了两个相同的数据呢?

由于抑或的结果为0所以无法再次使用抑或法。

但不变量法同样适用于这道题。

 

 

 

4、每个数据都有三个或多个备份时,丢失一个,两个或多个数据呢?

丢一个或两个的话比较简单:如果是偶数个相同备份的话,可以用抑或法或不变量法;奇数用不变量法。

丢多个的话:如果丢失的数字不多不大,且如果知道范围,我认为可以在得出和的方程和平方和的方程后用暴力枚举。

 

 

 

5、扑克牌中抽出一张牌,怎样快速地知道抽出的是哪一张(不含大小王)

抑或法同样适用,剩余牌抑或的结果就是抽出的那张牌。

如果要知道花色,可以让每种花色相加,最后哪个花色的和不是4的倍数抽出的牌就是哪种花色。

不变量法同样适用,扑克牌总和(1+2+3+…+13)x 4。然后减去剩余牌之和则知道抽出的牌。

    原文作者:a386STF
    原文地址: https://blog.csdn.net/a386STF/article/details/81088306
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞