剑指offer刷题记录51--数组中数字出现的次数

在这里插入图片描述
官方题解
在这里插入图片描述
在这里插入图片描述
在这里解释一下

因为异或运算规则为:两数相同的结果为0,不同的结果为1。所以异或整个数组,由于数组中所有相同的数值在异或运算中都变为0,导致结果只剩下两个不同的数值的异或:

例如:nums=[4,1,4,6],转换成二进制为0100,0001,0100,0110,那么对这四个数字进行异或,得到的结果为0001^0110,其实也就是数组中这两个不同数字异或的结果。

那么从上面可以知道,我们之后的操作只需要将这两个数字分出来就好。怎么分呢?还是以 nums = [4,1,4,6] 为例,nums里面所有的数字异或一遍得到的结果是 0111,要想将不同的两数分离,只需要在异或的时候选择一位与1(0001)的对应位相同,与6(0110)对应的位不同即可。那么该怎么找出这个位呢?

我们先来看这个整体的异或结果:0111,说明这两个不同的数值的不同位为0100,0010,0001(因为之前我们说过,整体的异或结果其实就是这两个不同数字的异或结果,且异或是不同为1),那么在这里可以选择最低位异或即可将其分出(其他位也可)。

当我们选择 0001的时候,0001 与 nums = [4,1,4,6] 所有的数字异或后得到的结果为:0101,0000,0101,0111。这样的话我们可以依据最后一位等于1的数划分一组,为0的数划分一组。得到两个数组:[1],[4,4,6]

最后,我们对这两组数分别进行异或,得到两个数:1,4^ 4 ^6 = 6 即1和6找到。

算法

(1)先对所有数字进行一次异或,得到两个出现一次的数字的异或值。
(2)在异或结果中找到任意为1的位
(3)根据这一位对所有的数字进行分组
(4)在每个组内进行异或操作,得到两个数字

代码如下:

在这里插入图片描述
在这里插入图片描述
有关位运算一类的题目 位运算合集

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值