数组中数字出现的次数

数组中数字出现的次数

题目1:数组中只出现1次的2个数字。

一个整形数组中除2个数字之外,其他数字都出现了2次。请找出这2个数字。

思路:任何一个数字异或它自己都等于0。如果异或整个数组,得到的结果就是数组中唯一出现一次的数字。根据这个思路,我们可以将本题的数组拆分成2个。

数组A:2个相同数字+唯一出现1次的数字。

数组B:2个相同数字+唯一出现1次的另一个数字。

如何拆分数组?

我们异或整个数组得到的结果就是该数组中唯一的2个只出现1次的数字的异或结果,这个结果非0,那么二进制中一定有1位不等于0。

我们根据这位不等于0将数组拆分成2部分,再单独异或得到的2个子数组。

参考代码:

root@gt:/home/git/Code# ./a.out _2jin:2 find1index:1
    data:1->1
data:2->0
    data:1->1
    data:3->1
    data:1->1
    data:1->1
data:2->0
data:2->0
6   4
root@gt:/home/git/Code# cat find2.c #include <stdio.h> int find1index(int _2jin)
{
    int res = 0;
    int num = _2jin;
    while((num & 1) == 0)
    {
        ++res;
        num = num >> 1;
    }
    printf("_2jin:%d\tfind1index:%d\n",_2jin,res);
    return res;
}

int isbit1(int data,int index)
{
    int res = 0;
    data = data >> index;
    if(data & 1 != 0)
    {
        res = 1;
        printf("\tdata:%d->%d\n",data,res);
    }
    else
        printf("data:%d->%d\n",data,res);
    return res;
}

void find2(int* pdata,int len,int* num1,int* num2)
{
    if(pdata == NULL || len <= 0)
        return;
    int _2jin = 0;
    for(int i = 0;i < len;++i)
        _2jin ^= pdata[i];
    int index = find1index(_2jin);
    *num1 = *num2 = 0;
    for(int i = 0;i < len;++i)
    {
        if(isbit1(pdata[i],index))
            *num1 ^= pdata[i];
        else
            *num2 ^= pdata[i];
    }
}

int main()
{
    int pdata[] = {2,4,3,6,3,2,5,5};
    int num1;
    int num2;
    find2(pdata,sizeof(pdata)/sizeof(int),&num1,&num2);
    printf("%d\t%d\n",num1,num2);
    return 0;
}

题目2:数组中唯一出现1次的数字。

在一个数组中除了一个数字出现1次,其他数字都出现3次。

思路:我们把数组中所有数字的二进制表示的的每一位加起来,如果某一位的和能被3整除,那么那个只出现1次的数字的二进制表示中该位为0.

参考代码:

root@gt:/home/git/Code# ./a.out 0 i:0   temp = 1
1 i:1   temp = 2
1 i:2   temp = 4
0 i:3   temp = 8
0 i:4   temp = 16
0 i:5   temp = 32
0 i:6   temp = 64
0 i:7   temp = 128
0 i:8   temp = 256
0 i:9   temp = 512
0 i:10  temp = 1024
0 i:11  temp = 2048
0 i:12  temp = 4096
0 i:13  temp = 8192
0 i:14  temp = 16384
0 i:15  temp = 32768
0 i:16  temp = 65536
0 i:17  temp = 131072
0 i:18  temp = 262144
0 i:19  temp = 524288
0 i:20  temp = 1048576
0 i:21  temp = 2097152
0 i:22  temp = 4194304
0 i:23  temp = 8388608
0 i:24  temp = 16777216
0 i:25  temp = 33554432
0 i:26  temp = 67108864
0 i:27  temp = 134217728
0 i:28  temp = 268435456
0 i:29  temp = 536870912
0 i:30  temp = 1073741824
0 i:31  temp = -2147483648

6
root@gt:/home/git/Code# cat find1.c #include <stdio.h> 
int find1(int* num,int len)
{
    if(num == NULL || len <= 0)
        return 0;
    int bitSum[32] = {0};
    for(int i = 0;i < len;++i)
    {
        int bitMask = 1;
        for(int j = 0;j < 32;++j)
        {
            int bit = num[i] & bitMask;
            if(bit != 0)
                ++bitSum[j];
            bitMask = bitMask << 1;
        }
    }

    unsigned int res = 0;
    unsigned int temp = 0;
    for(int i = 0;i < 32;++i)
    {
        printf("%d ",bitSum[i] % 3);
        temp = (unsigned int)1 << i;
        printf("i:%d\ttemp = %d\n",i,temp);
        if(bitSum[i] % 3 != 0)
            res += temp;
    }
    return res;
}

int main()
{
    int num[] = {1,1,2,2,3,3,4,4,5,5,6,5,4,3,2,1};
    int res = find1(num,sizeof(num)/sizeof(int));
    printf("\n%d\n",res);
    return 0;
}

    原文作者:ailx10
    原文地址: https://zhuanlan.zhihu.com/p/34598430
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞