算法总结-位运算(正在更新)

参考:https://mp.weixin.qq.com/s/o3pEkayhuMXkl9fp1wA0XA

简述

所有数在计算机内存中都是以二进制的形式存储,位运算是直接对二进制位进行操作,因此处理速度上具有优势。当然,如果计算机的计算效率非常之快,二进制运算的优势并非很抢眼,但是位运算有一些经典应用,还可以用位运算优化程序。下面一起来看看吧:

位运算的计算规则和使用示例

计算规则:

(1)and运算

通常用于二进制取位操作,例如一个数与 1相与的结果就是取二进制的最末位,可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数。

(2)or运算

通常用于二进制特定位上的无条件赋值,例如一个数与1相或的结果就是把二进制最末位强行变成1。

(3)xor运算

相同取0,不同取1,通常用于对二进制的特定一位进行取反操作,两次异或同一个数最后结果不变,即(a xor b) xor b = a。

(4)not运算

把内存中的0和1全部取反。使用not运算时要格外小心,需要注意整数类型有没有符号,若是无符号整数,那么得到的值就是它与该类型上界的差。

(5)位移运算

左移动1位,各位数计算都会乘以2;右移1位,各位数计算都会除以2。x<<N,x乘以2的N次方;x>>N, x除以2的N次方。

使用示例:

(1)判断奇偶

a&1 等于0 ,a为偶数;等于1,a为奇数。

(2)判断正负数

int b = a>>31 , b=0 则为正,b=1则为负。

(3)取int a的第k位

a >> k & 1。

(4)取相反数

a的相反数 ~a+1。

(5)不用中间变量交换两个数值

void swap(int a, int b){
a ^= b;
b ^= a;
a ^= b;
}

(6)取绝对值

int abs(int a){
int b;
a = b >> 31;
return (a ^ b) - b;
}

实例解析

题目1:只出现一次的数字

题目描述:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
解题思路:对位运算符的应用。
(1)交换律:a ^ b ^ c <=> a ^ c ^ b
(2)任何数与0异或为任何数:0 ^ n => n
(3)相同的数异或为0:n ^ n => 0
注:下面代码可左右滑动查看

class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for(int i = 0; i < nums.length; i++){
            res ^= nums[i];
        }
        return res;
    }
}

题目2:二进制数1的个数

题目描述:写一个函数操作无符号整数,返回整数的二进制数1的个数
示例 1:
输入: 00000000000000000000000000001011
输出: 3
解释:输入的二进制串00000000000000000000000000001011 中,共三位为 ‘1’
示例 2:
输入: 00000000000000000000000010000000
输出: 1
解释:输入的二进制串00000000000000000000000010000000 中,共一位为’1’。
解题思路:对位操作的应用,使用n&(n-1)的方法(该方法可以将最后一位1变为0),发现有几个1,就循环几次n&(n-1)得到0。时间复杂度:O(M),M是n中1的个数。
注:下面代码可左右滑动查看

public class Solution { 
    public int NumberOf1(int n) { 
        int count = 0; 
        while (n != 0) { 
            n &= (n - 1); 
            count ++; 
        } 
        return count; 
    } 
}
```  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值