《剑指offer》:数组中只出现一次的数字

本文介绍了一种高效算法,通过异或运算找出数组中仅出现一次的两个数字,避免了使用额外空间。首先全局异或找到两个唯一数的异或结果,再按位分组异或,最终得出这两个数字。

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

如果是只有一个数字,那么当然可以直接将全部元素进行异或,最后得出那个只出现一次的元素,原理就是一个元素和自己本身异或为0,且元素之间异或的顺序不影响最后的结果。

那么如果有两个数字都出现了一次呢?可以使用HashMap来存储每个元素出现的次数,最后再进行寻找。但是我们还是要掌握一下如何使用异或来解决这个问题:
首先我们还是先将所有元素进行异或,那么我们此时得到的结果是那两个元素异或的结果,加入结果中有某一位是1,那么肯定两者之中有一个是1有一个是0。我们再将所有元素进行分组,此位置是1的到一组,此位置是0的到一组,那么要求的两个元素肯定分到了不同的组中。这样就变成了两个子问题。这两个子问题就是第一种情况,即每个数组中只有一个数字出现过一次,其它的都出现过两次。然后分别去异或就可以得到结果了:

    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        int result = array[0];
        for(int i = 1; i < array.length; ++i)
            result = result ^ array[i];  //先将所有元素进行异或
        int temp = 1;
        while((result & temp) == 0) temp = temp << 1;  //求最末尾的一个1
        int result1 = 0, result2 = 0;  //这个地方要初始化为0
        for(int i = 0; i < array.length; ++i) {
            if ((array[i] & temp) == 0)   //根据此位上为0或者1,分成两组进行异或
                result1 = result1 ^ array[i];
            else 
                result2 = result2 ^ array[i];
        }
        num1[0] = result1;
        num2[0] = result2;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值