题解 | #数组中只出现一次的两个数字#
数组中只出现一次的两个数字
http://www.nowcoder.com/practice/389fc1c3d3be4479a154f63f495abff8
重复数字,第一反应是用map来做,但是map的方法需要空间复杂度O(n),那么还有其他方法吗?
看了别人的方法,用异或可以做,原因是题目中只有两个数出现一次,其他数都出现了两次,而异或可以将两个相同的数运算变为0。可以得知对整个数组内的数逐次异或后,最终结果为a^b,这就是我们想获得的数。
那么如何获得a和b呢,我们可以考虑将数组分为两部分,a...和b...,其中要求a数组中所有数都出现两次,除了a,b数组中也一样。怎么划分呢,从a和b的区别开始,a和b的异或结果的二进制中,如果出现某一位为1,就表示a和b中的那一位不一样,依次为据,那一位与a相同的,进入a这一组,反之进入b这一组。
代码如下:
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param array int整型vector * @return int整型vector */ vector<int> FindNumsAppearOnce(vector<int>& array) { // write code here int l = array.size(); int ret = 0; int m = 1; vector<int> ans(2); for(int i=0;i<l;i++){ ret ^= array[i]; } while((ret&m) == 0){ m = m<<1;} for(int i=0;i<l;i++){ if((m&array[i]) == 0){ ans[0] ^= array[i]; } else{ ans[1] ^= array[i]; } } if(ans[0] > ans[1]) swap(ans[0], ans[1]); return ans; } };
这里讲一下&,这是一个位运算符和&&不一样,&&是逻辑运算符,用不同位为1依次去计算最终结果,如果ret中对应位为1则输出大于0的数,反之则为0,由此可得。