剑指 Offer 56 - II. 数组中数字出现的次数 II

思路:1.遍历数组,新建一个长度为32的数组统计每个数字二进制位1出现的次数。

           2.然后每个元素对3取余,得到只出现一次的数字的各二进制位。

           3.利用左移和或运算还原该数。

对我来说的问题在于最后一步的循环,是先赋值再移位还是先移位再赋值。

思考了一会才得出的答案。

剑指 Offer 56 - II. 数组中数字出现的次数 II

 

再贴一个移位操作的帖子。

https://blog.csdn.net/qq_31964019/article/details/106048836

class Solution {
    public int singleNumber(int[] nums) {

        //因为int4个字节,32位
        int[] counts = new int[32];
        int n = 1;

        //记录所有数字的各二进制位1出现次数。
        for(int num : nums){
           for(int j = 0; j < 32; j++){
               //因为n=1,所以每次记录最低位是否为1
               if((n & num) == 1)
                   counts[j]++;
                num >>>= 1;
           }
        }

        /*
        * 将计数数组counts每一位%3,得到res的各个二进制位
        * counts[0]存的是第32位(最低位)1的数量
        * counts[31]存的是第1位(最高位)1的数量
        * 循环需要将最高位存入res,然后进行31次左移
        * 二进制位赋值操作需要32次,左右一次给最低位赋值后不需要左移
        * 所以需要循环32次,先移位最后赋值
        */
        int res = 0, m = 3;
        for(int j = 0; j < 32; j++){
            res <<= 1;
            res |= counts[31 - j] % 3;
        }
        return res;
    }
}

 

posted @ 2021-03-26 12:43  星予  阅读(44)  评论(0)    收藏  举报