题目在这:https://leetcode-cn.com/problems/single-number-iii/
法一(哈希表):
直接使用哈希表。元素值为key 其出现的次数为value。直接遍历哈希表输出value为1的key。
完整代码:
法二 (异或位运算):
异或运算:
a ^ a = 0
a ^ b = 1
即相同为0,不同为1. 这里的相同不同是在二进制下做的对位比较。
我们对整个字符串进行异或,只会剩下两个只出现了一次的字符的异或结果。
比如字符串: aabbcddeff aa异或为0 bb异或为0.。。。。。最后只会剩下c和e进行异或。我们拿到这个结果记为res。
我们重新遍历原字符串,使用某种方法对原来的字符串进行分类。是他们分成两拨。这两个只出现一次的字母分别在不同的批次里。 即 A批次只有一个只出现了一次的数字,其他都是一对一对的。B批同理。
那这个方法是什么呢?
上面说过,异或二进制对位不同的情况下为1。由于结果res为两个不同数字异或出来的结果,所以res的二进制数必然有1。我们需要找到这个数字1从右边数的位置,设一个数 h = 1让他和res不断的进行 与 操作。 如果为0则让h往左挪一位。右边空出来的地方补0,这样操作下去的结果就是h会变成 1后面跟着N个0。即此时已经找到了右边数的第一个1的位置。
再简单点说~这个所找到的1的位置,是两个只出现一次的数,这俩数在该位置上必然是一个为0一个为·1,异或出来就是结果为1.
所以重新遍历数组,让h和每一个数进行 与 操作,必然可以将两个只出现一次的数分到不同的组中,其他一对一对的数分配的如何我们不考虑,只要能吧两个只出现一次的数分开即可。
最后再次异或两个分组,得到的就是两个只出现一次的数字了。
完整代码