leetcode_single number

来源:互联网 发布:startos软件中心 编辑:程序博客网 时间:2024/05/18 00:29

题目描述

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory

注:一组数每个数都出现两次除了其中某个数,请找出这个只出现一次的数,不适用额外空间。

解析思路

关于计数问题常考虑hashmap,可以通过键值对应进行计数,然后遍历查找只出现一次的数据,时间复杂度和空间复杂度都是O(N),这里题目要求额外空间复杂度O(1),一种方法是遍历数组元素,全部数组元素进行异或运算,最后结果就是那个只出现一次的数据,我们可以自己写几组测试数据分析下,基本思想就是 A^B^C^B^C = A ,这里我们不使用这种方法,因为leetcode上还有一道题目是数组中元素除了某个元素只出现一次外,其他元素都出现三次,然后让我们寻找这个元素,这样的话,上述异或方法就不适用了。

我们的思路是将每个数看成二进制序列,int型32位即可表示(当然程序中要考虑正负数问题),我们这里主要讲述思想,明白了之后具体细节可以参考代码理解。我们对N个数的bit0~bit31分别进行求和运算,求和mod2运算(对于出现k次则就是求和mod k),也就是N个数的bit0叠加得到结果的bit0,N个数的bit1叠加得到结果的bit1,类似地我们得到结果的bit0….bit31,(高低位自行设定,保持一致)然后组成最终结果。

我们以bit0为例进行分析,N个数中假设除了目标数外每个数都出现K此,假设除了目标数外的N-1个数中有x个数bit0为0,N-1-x 个数bit0 为1,目标数的bit0 为 b,则求和结果为(N-1-x)K +b ,求余后得到b,也就是目标数的bit0,所以按照上述方法可以得到目标数的二进制序列。具体编码中要使用移位运算和与运算,时间复杂度O(n).

详细代码

public int singleNumber(int[] A) {    //r is the return value    int r=0;    int mask = 1;    for(int i=1;i<=32;i++)    {        int bit = 0;        for(int j=0;j<A.length;j++)        {            //remember the priority of the operators  "+" is higher than"<<"            int tmpbit = (A[j]&mask)>>(i-1);            //cuz java doesn't has unsigned int, we should deal with the negative integer            if(A[j] <0)            {                tmpbit = tmpbit&1;            }            bit = (bit+tmpbit)%2;        }        mask = mask<<1;        if(bit == 1)        {            r = r|(bit<<(i-1));        }    }    return r;}
0 0
原创粉丝点击