这个题目源自面试题:有1001个数,它们都在1~1000的范围内,其中只有一个是重复的,求找出这个数。
我的一个同学在吃饭聊天的时候,给我说这种题的时候,但是他把题设“这些数都在1~1000的范围内”给漏了,于是他想让我在不知道这些数是什么数的情况下,用异或法来做,并且尽量有时间复杂度为o(n)。在一度怀疑自己智商的情况下,上网搜索了之后,我才发现,如果不告诉这些数的范围,异或法是做不出来的。
先说一下对于这种N+1的重复数问题,在告诉数的范围的情况下,为什么异或法可以做出来。
前提:异或运算满足交换律,结合律,并且X ^ X = 0, X ^ 0 = X。
对于N+1个数,例如N=1000,那么我们首先有一个变量 n=1^2^...^1000 ; 可以认为变量 n 存储的是一个异或表达式,而不仅仅是一个抑或运算的结果。更可以想象为变量n 在逻辑上创造了一个数的空间,这个数的空间内包含一千个不重复的数。那么当我们将 N+1个数,也就是 1001 个待解决的数逐个和 n 进行异或运算时,利用交换律和结合律,我们可以不断的在 n 所代表的异或表达式中进行销项(在 n 所代表的的逻辑上的数的空间中进行数的移除)。对于重复的那个数出现时,也即该数第二次与 n 异或时,因为其无法销项,所以会一直保留在异或表达式中直到最后输出。
所以,异或法可以理解为在逻辑上开辟了一个存储空间。因其是逻辑上的,所以就不具有什么物理上的操作性。
按照上面这个思路也就不难解释为什么在不知道是哪些数的情况下,无法用异或法求解N+1的重复数的问题了。因为,在这种情况下,你无法构造一个覆盖待解决数的范围的异或表达式/数的空间,所以也就无法“过滤”掉非重复数,所以无法求出重复的数。
这里贴一个可以参考的链接:http://www.cnblogs.com/suoloveyou/archive/2012/04/25/2470292.html