昨天在leetcode上写到一道题,给出一个整形数组,这个数组当中有很多不同的整数,这些整数当中只有一个数字只出现一次,其他的整数都出现两次。题目的要求:找出数组中只出现一次的数字,不开辟另外的数组空间实现。看到题目之后,我根本就想不到不开辟数组空间的方法实现,果断看评论,然后知道了c++里面的异或操作,这题可以根据异或操作(^)来实现。以下我给出自己证明证明为什么这道题可以用异或来实现。
规定
”异或“用”^“来表示,“与”用”·“来表示,“或”用“+”来表示。
(A^B)^B=A证明
根据数字电路的知识,给出以下证明:
(A^B)^C=(A^C)^B证明
根据上述化简的结果,很容易可以发现表达式里面的对称性,证得(A^B)^C=(A^C)^B=(B^A)^C=(B^C)^A=(C^A)^B=(C^B)^A,也即是三个变量接2个或异门,最终的结果与接入的前后顺序无关。
结论
根据上面两个式子可以得出下面这个结论,依次对数组中的整数做异或操作,((A^B)^C)^A=B^C,我们可以把A看成是数组中出现了两次的数字,B和C两次A出现时中间出现过的数字,惊奇地发现,A进行了两次异或之后A就跟没有进行过异或一样,无论A出现的位置先后。
由于计算机中整型数据的本质是一堆0和1以补码的形式存储,有了上面的证明,“只出现一次的数字”就是对数组中元素依次异或最终得到的数字,出现两次的数字都是进行了两次异或的数字,被”抵消“了。
拓展:对整型数组中的数字依次做异或,最终的出来的数字是对整型数组中出现奇数次的数字做异或的结果,根据这个结论可以灵活地解其他地变式的题目。
上天保佑,希望我期末考试别挂科。