数组中的只有1 (或2)个数字是单独出现的,其他的都是成对出现的,请找出单独出现的这1(或2)个数字

这道题其实是一道进阶题,它的初级是:
一个数组中只有一个数是单独出现的,其他的都是成对出现的,请找出这个数。
大家首先想到把这个数组遍历一遍,然后进行各种操作,但是这里推荐使用一种效率更高的方法——把数组中所有元素都异或一遍,最后得到的结果就是那个单独出现的数字。
例如数组元素:1 2 4 2 1。
1^2 = 3 (0001 ^ 0010 = 0011)
3^4 = 7 (0011 ^ 0100 = 0111)
7^2 = 5 (0111 ^ 0010 = 0101)
5^1 = 4 (0101 ^ 0001 = 0100)
最后结果为4

代码实现:

int separate_figures(int *number, int size)
{
    int i = 0;
    int num = number[0];
    for (i = 1; i <size; i++)
    {
        num ^= number[i];
    }
    return num;
}



int main()
{
    int arr[] = { 1, 2, 3, 4, 3, 2, 1 };
    int sz = sizeof(arr) / sizeof(arr[0]);

    int ret = separate_figures(arr, sz);

    printf("单独出现的数字数是:%d\n", ret);

    system("pause");
    return 0;
}

这里写图片描述

用这样的算法来做的话这道题就变的很简单了,现在来看看这道题的进阶版
数组中的只有2个数字是单独出现的,其他的都是成对出现的,请找出单独出现的这2个数字
代码如下:

#include <stdio.h>
#include <windows.h>

void find_single(int *number, int size)
{
    int i = 0;
    int key = number[1];
    int n = 0;
    int m = 0;
    int flag = 1;

    for (i = 1; i < size; i++)
    {
        key ^= number[i];   //把整个数组的元素异或,存到key里面
    }

    for (i = 0; i < 32; i++)  //找出key的二进制序列里面第一次出现1的位置(从右到左查找)
    {
        if (key & (flag<<=i))
        {
            break;
        }
    }

    if (flag)
    {
        for (i = 0; i < size; i++)
        {
            if (flag & number[i])
            {
                n ^= number[i];
            }
            else
            {
                m ^= number[i];
            }
        }
        printf("%d, %d\n", n, m);
    }
    else
    {
        printf("这个数组中没有单独出现的数字!\n");
    }
}


int main()
{
    int arr[] = { 1, 1, 2, 2, 3, 3, 4, 5 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    find_single(arr, sz);
    system("pause");
    return 0;
}

这里写图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值