LeetCode-位运算总结-461. 汉明距离、268. 缺失数字

目录

总结:位运算

461. 汉明距离

268. 缺失数字


总结:位运算

基本原理:

  • 二进制数在内存中是以补码的形式存放的
  • 正数的补码,反码都是其本身,
  • 负数的补码是:符号位不变,其余各位求反,末位加1 ;反码是:符号位为1,其余各位求反,但末位不加1 。

   0s 表示一串 0,1s 表示一串 1。 

x ^ 0s = x      x & 0s = 0      x | 0s = x
x ^ 1s = ~x     x & 1s = x      x | 1s = 1s
x ^ x = 0       x & x = x       x | x = x
  • 利用 x ^ 1s = ~x 的特点,可以将位级表示翻转;利用 x ^ x = 0 的特点,可以将三个数中重复的两个数去除,只留下另一个数。
  • 利用 x & 0s = 0 和 x & 1s = x 的特点,可以实现掩码操作。一个数 num 与 mask:00111100 进行位与操作,只保留 num 中与 mask 的 1 部分相对应的位。
  • 利用 x | 0s = x 和 x | 1s = 1s 的特点,可以实现设值操作。一个数 num 与 mask:00111100 进行位或操作,将 num 中与 mask 的 1 部分相对应的位都设置为 1。

位与运算技巧:

  • n&(n-1) 去除 n 的位级表示中最低的那一位。例如对于二进制表示 10110100,减去 1 得到 10110011,这两个数相与得到 10110000。
  • n&(-n) 得到 n 的位级表示中最低的那一位。-n 得到 n 的反码加 1,对于二进制表示 10110100,-n 得到 01001100,相与得到 00000100。
  • n-n&(~n+1) 去除 n 的位级表示中最高的那一位。
  • 计算机中的负数是以其补码形式存在的,负数的补码=原码取反+1,即-n=~n+1

移位运算:

  • >> n 为算术右移,低位移出,高位的空位补符号位,即正数补零,负数补1。相当于除以 2^{^{n}}
  • >>> n 为无符号右移,忽略了符号位扩展,最高位补0;
  • << n 为算术左移,高位移出,低位的空位补零。相当于乘以 2^{^{n}}

掩码:(英语:Mask)在计算机学科及数字逻辑中指的是一串二进制数字,通过与目标数字的按位操作,达到屏蔽指定位而实现需求。

  • 要获取 111111111,将 0 取反即可,~0。
  • 要得到只有第 i 位为 1 的 mask,将 1 向左移动 i-1 位即可,1<<(i-1) 。例如 1<<4 得到只有第 5 位为 1 的 mask :00010000。
  • 要得到 1 到 i 位为 1 的 mask,1<<(i+1)-1 即可,例如将 1<<(4+1)-1 = 00010000-1 = 00001111。
  • 要得到 1 到 i 位为 0 的 mask,只需将 1 到 i 位为 1 的 mask 取反,即 ~(1<<(i+1)-1)。

Java 中的位操作

  • static int Integer.bitCount();            // 统计 1 的数量
  • static int Integer.highestOneBit();   // 获得最高位
  • static String toBinaryString(int i);    // 转换为二进制表示的字符串

以上引自:https://www.cnblogs.com/xiaojiaojiao/p/10706427.html

java中按位取反运算符“~”参考:https://blog.csdn.net/smilecall/article/details/42454471


461. 汉明距离

【题目】:

【代码】:

方法1:对x,y两个数进行异或操作,异或结果转为二进制,统计有多少个 1 即可。

但是效果不太好:

 

方法2:对x,y两个数进行异或操作,得到ret,ret的二进制每次右移1位与1相与,由于1的高位全为0,1只有与1相与才得到1,统计有多少个 1 即可。

效果:

 

方法3:使用 z&(z-1) 去除 z 位级表示最低的那一位。

效果:

 

方法4:使用 Integer.bitcount() 来统计 1 个的个数。

效果:

 


268. 缺失数字

【题目】:

【代码】:

方法1:用0到n的和减去数组中数的和,提交正确,但是如果实际数组中数据太大可能会有溢出。

效果:

 

方法2:使用异或运算^进行 抵消,剩下的数字就是缺失的

效果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值