数组中只出现一次的数字

https://mp.csdn.net/mp_blog/creation/editor

思路就是:

1.两个相同的数异或的结果是0

2.0跟任何数异或的结果都是0

3.这个数组中,有两个数是只出现一次,我们对这个数组所有数进行异或,相同的数都抵消,最后异或的结果就是只出现一次的两个数

4.我们得到这个ret结果,但是如何根据这个结果去得到原本的两个数???

5.假设这个ret的某一位上是1,那么这个数组里肯定分成两个组(一个组是这个位上是0,一个组这个位上是1,并且相同的数据在同一组)

比如这一位是第一位,1 的第一位就是1 ,此时两个1都在同一组,那么两个 2 就在另一组

最重要的一点是:这两个数既然只出现一次,说明他们两个不在同一组,然后他们两个互相所在的组存在相同的数据,那么我们就去判断数组中这一位是1的那一组与0去异或得到最后的数就是其中一个

另外一个也是如此.

6.有两个小细节:

第一:((flg << i) & ret) != 0 这里当时我写的是 == 1,但是错了 我没有理解 & 的概念 

如果你写 == 1,是对这个 & 的总结果判断大小,实际上我们判断的是那一位是不是1,

假设 0001  & 0110 (遇0则0) 此时假设我们判断第二位, 0110  & 0010 此时 结果就是0010

说明这个总结果不是0,意味着他这个位肯定是1,如果总结果是0,其余位本来就通过按位与变成了0,这一位恰好又是0,这个时候就是0

所以你不能写 == 1,应该时候 != 0,保证你这个数结果不是0,说明这个位肯定是1啊

7.flg = flg << i

这个为什么还要执行,因为你之前只是让flg左移i然后 & ret的结果去判断,如果满足的话,flg实际上并没有改变,你还需要去手动让他左移保证flg是左移后的结果

最后你再去判断(array[j] & flg) == 0 来进行分组

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array, int num1[], int num2[]) {
        if (array == null || num1 == null || num2 == null) {
            return;
        }
        num1[0] = 0;
        num2[0] = 0;
        int ret = array[0];
        for (int i = 1; i < array.length; i++) {
            ret ^= array[i];
        }
        //此时得到了那两个只出现一次的数异或的结果
        int size = Integer.SIZE;
        int flg = 1;
        int i = 0;
        while (size >= 0) {
            size--;
            if (((flg << i) & ret) != 0) {
                flg = flg << i;
                break;
            }
            i++;
        }
        
        for (int j = 0; j < array.length; j++) {
            if ((array[j] & flg) == 0) {
                num1[0] ^= array[j];
            } else {
                num2[0] ^= array[j];
            }
        }

    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值