数组中只出现一次的两个数字

来源:互联网 发布:java nio 关闭连接 编辑:程序博客网 时间:2024/04/28 18:44

哈哈,好多分析

本题的思路如最后一个功能函数所示:
由算法思路可得:总共的时间复杂度是O(n)
因为,第一步,数组全部遍历一边,相等的数位运算异或后为0,剩下两个不同的异或后不为0
功能函数1:要是异或后不为零的数,寻找第一个不为零的那一位
功能函数2:寻找某一位为0,以及为1的数
两个功能函数写完后,继续第二遍遍历,用功能2函数,把某一位为1的数,和*num1做异或,最后能得到一个只出现一次的数,同理,得到另一个出现一次的数,即就是,把某一位为0的数,和*num2做异或,可得到另一个出现一次的数
整体思想是,运用了异或可得到只出现一次的不同的数,然后将要求得的两个数分在两个数组里,但是这里并没有重新赋值新数组的过程,而直接对某一类的数进行异或,并且分类过程可以把出现两次的数,分为一类,显而易见
啰里啰嗦的感觉,还是想分析一下,为啥就能把两个数刚好分开来,因为,yihuo得到的是最后两个不同的数异或的结果,
寻找第一位为1的位,说明这两个数这一位是不同的,所以根据0和1就能把两个数分开来

class Solution {public:   //对于位运算更加熟悉一点    int FindFirstBitIs1(int number)    {    int index  = 0;        while(!(number&1)){            number=number>>1;            index++;        }        return index;    }    bool IsBit1(int data, int index)    {           //借助移位,位与的方式来判断某位的情况,这种使用方法需要好好熟悉一下        data=data>>index;//右移index位        return (data&1);//查看右移后第一位是否为1    }    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {int len=data.size();        if(len<2)            return;        int yihuo = 0;        for(int i = 0; i <len; i++){            yihuo ^=data[i];        }        unsigned int indexof1 =  FindFirstBitIs1(yihuo);        *num1=*num2=0;        for(int i = 0; i<len; i++){            if(IsBit1(data[i],indexof1))                *num1^=data[i];            else *num2^=data[i];        }            }    };


原创粉丝点击