数组中仅出现一次的两个数-异或

本文介绍了一种高效算法,用于从整数数组中找出仅出现一次的两个数字。利用异或运算特性,实现了时间复杂度O(n)、空间复杂度O(1)的要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
题意:
一个整型数组里除了两个数字之外,其他的数字都出现了偶数次,
请写程序找出这两个出现一次的数字。
要求时间复杂度是O(n),空间复杂度是O(1).

解题思路:用异或操作
偶数个的异或起来为0,所以最后异或的答案等于所求两数异或和
这两个数不一样那么异或结果一定至少有一位为1。表示num1该位为1,num2该位为0。
将该位为1的数全部异或起来,得到的结果是num1。
这是因为除了num1之外,剩下的每个数(当然不包括num2)一定有偶数个。
同理将该位为0的数全部异或起来,得到的结果是num2。
*/
#include <stdio.h>

unsigned int FindFirstBitIs1(int num)
{
      int indexBit = 0;
      while (((num & 1) == 0) && (indexBit < 32))
      {
            num = num >> 1;
            ++ indexBit;
      }
      return indexBit;
}

bool IsBit1(int num, unsigned int indexBit)
{
      num = num >> indexBit;
      return (num & 1);
}

void FindNumsAppearOnce(int data[], int length, int &num1, int &num2)
{
      if (length < 2)///即第一个和第二个数
            return;
      int resultExclusiveOR = 0;
      for (int i = 0; i < length; ++ i)
            resultExclusiveOR ^= data[i];

      ///找到第一位(2进制)是1的
      unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
      num1 = num2 = 0;
      for (int j = 0; j < length; ++ j)
            if(IsBit1(data[j], indexOf1))///该位为1的异或起来
                  num1 ^= data[j];
            else
                  num2 ^= data[j]; ///该位不为1的异或起来
      }
}

int main()
{
    int n,i,x,y;
    int a[99999];
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        FindNumsAppearOnce(a,n,x,y);
        printf("%d\n",x+y);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值