力扣第136、137:只出现一次的数字(位运算)

一、位运算简介

        位操作是程序设计中对位模式按位或二进制数的一元和二元操作。在许多古老的微处理器上, 位运算比加减运算略快, 通常位运算比乘除法运算要快很多。它主要有

& 按位与、| 按位或、^ 按位异或、~取反、>>右移、<<左移 这六种运算符组成。他们的基本操作如下:

1、&按位与

运算规则:1&1=1,1&0=0,0&1=0,0&0=0。只有两数都为真时,结果才为真。

        int a=4                //0000 0100

        int b=5                //0000 0101

        int c=a&b= 4       //0000 0100        

2、|按位或        

        运算规则:1|1=1,1|0=1,0|1=1,0|0=0。只有两数都为假时,结果才为假。

        int a=4                //0000 0100

        int b=5                //0000 0101

        int c=a|b= 5        //0000 0101        

3、^按位异或

        运算规则:1^1=0,1^0=1,0^1=1,0^0=0。只有两数相同时为假,不同是为真(用途广)

        int a=4                //0000 0100

        int b=5                //0000 0101

        int c=a^b= 1        //0000 0001        

4、按位取反

        运算规则:~1=0,~0=1。1变成0,0变成1即可

5、<<左移、>>右移

        运算规则:<<,>> 位移运算,左位移最低位补0,右位移符号位后 最高位补0

        int a=5;        //0000 0101

        int b=a<<1=10        //0000 1010(相当于乘以二)

        int c=a>>1=2        //0000 0010(相当于除以二)

二、题目内容

力扣第136、137:只出现一次的数字(位运算)_第1张图片

 力扣第136、137:只出现一次的数字(位运算)_第2张图片

三、题目分析

        第一题中,数组中有一个数字只出现一次,其余均出现两次。我们用位运算的做法时,将数组的数做异或处理,这样一来,出现两次的数异或后肯定为0,而那出现一次的数和0异或,结果就是出现一次的数的值,这样就很快做出来了。

        对于第二题,一个元素出现一次,其余元素出现三次。肯定不能用上面的方法了。那么我们可以统计每一元素对应二进制位上的一的个数,然后相加,然后对3取余,就得到了出现一次的数。它的原理是

        力扣第136、137:只出现一次的数字(位运算)_第3张图片

         出现三次的数对3取余后正好得到了出现一次的元素的二进制位上的数。

四、代码

//第一题
class Solution {
    public int singleNumber(int[] nums) {
        int c=nums[0];
        for(int i=1;i

        力扣第136、137:只出现一次的数字(位运算)_第4张图片

//第二题
class Solution {
    public int singleNumber(int[] nums) {
         int ans = 0;
        for (int i = 0; i < 32; ++i) {
            int total = 0;
            for (int num: nums) {
                total += ((num >> i) & 1);
            }
            if (total % 3 != 0) {
                ans =ans| (1 << i);
            }
        }
        return ans;
    }
}

 力扣第136、137:只出现一次的数字(位运算)_第5张图片

你可能感兴趣的:(位运算,leetcode,算法,java)