题解 | #数组中只出现一次的两个数字#

数组中只出现一次的两个数字

https://www.nowcoder.com/practice/389fc1c3d3be4479a154f63f495abff8

解题思路:

  • step 1:遍历整个数组,将每个元素逐个异或运算,得到a⊕b。

# 这个是完全能够理解的,两个数一样的异或,变成0。

  • step 2:我们可以考虑位运算的性质,找到二进制中第一个不相同的位,将所有数组划分成两组。

# 这里为什么是找到1,是因为1的数据,表示之前a和b异或运算的不同位,才有1的结果,所以是对k&target,求位 k << = 1

# 这里经过实例后,可以得到结果。

  • step 3:遍历数组对分开的数组单独作异或连算。

# 这里还是依旧要做异或运算的,跟之前没有区别,只是通过k值 &区分了,两个不同的数。

# 0 异或 上一个数,得到的就是,那个数!!

  • step 4:最后整理次序输出。

实例演示:

可以用[1,4,1,6],演示就知道了

  • step 1:遍历整个数组,将每个元素逐个异或运算,得到a⊕b。

[001, 100, 001, 110] ,异或运算后得到 target = 010,也就是2

  • step 2:我们可以考虑位运算的性质,找到二进制中第一个不相同的位,将所有数组划分成两组。

k = 1,通过k找出,a和b不同的位,因为之前异或运算剩下的值,就是不同的位,k= 010,也就是2

  • step 3:遍历数组对分开的数组单独作异或连算。
  • (k & num[i] == 0) 区分不同数, a ^= num[i],去掉相同的数。

  • step4:最后整理次序输出。

return a<b?new int[]{a,b}:new int[]{b,a};

总之在于理解关键点

过滤掉相同数:异或 a⊕b,

找出不同数: 异或后,找出不同位,

在通过 与不同位,区分两个数,再异或得结果。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型一维数组
     */
    public int[] FindNumsAppearOnce (int[] nums) {
        int target = 0;
        for(int i=0; i<nums.length; i++) {
            target ^= nums[i];
        }

        int k = 1;
        while((k&target) == 0) {
            k <<= 1;
        }

        int a = 0, b = 0;
        for(int i=0; i<nums.length; i++) {
            if((k & nums[i]) ==0) {
                a ^= nums[i];
            } else {
                b ^= nums[i];
            }
        }

        return a<b?new int[]{a,b}:new int[]{b,a};
    }
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务