当前位置: 首页 > news >正文

优选算法-常见位运算总结

1.基础位运算:

>> :右移运算符:

  • 逻辑右移(无符号数):高位补 0,低位直接丢弃。
    示例:8 >> 2(二进制 1000 右移 2 位)结果为 0010(十进制 2)。

  • 算术右移(有符号数):高位补符号位(正数补 0,负数补 1),低位丢弃。

  • 示例:-8 >> 2(假设 8 位二进制 11111000 右移 2 位)结果为 11111110(十进制 -2)

  • 应用场景

  • 快速除以 2 的幂次。x>>n等价于:x/(2^n)

<<:左移运算符:

        将一个数的二进制表示向左移动指定的位数,右侧空出的位用 0 填充。

        x<<n,等价于 (x) 乘以 2 的 (n) 次方。

&:按位与:同1为1,有0为0.

|:按位或:有1为1,同0为0.

^:异或:相同为0,相异为1;无进位相加。

2.求一个数x的二进制位的第n 位是0还是1(最右侧为第0位):

(x>n)&1

3.将一个数x的二进制的第n位改成1(最右侧为第0位):

(1<<n) | x

4.将一个数x的二进制的第n位改成0(最右侧为第0位):

~(1<<n) | x

5.位图的思想:

使用int的二进制位32位:0~31,每一位有两种状态0,1.分别表示不同的含义。

6.获取一个数x的二进制位的最右侧的1: 1100 -> 0100

x&(-x)

-x:将x的最右侧的1的左侧的二进制都取反,1右侧保持不变;

x:1100  -x:0100

x&(-x)得到的就是1和1左边的二进制数,而1又是最右侧的,就得到了最右侧的1

7.删除一个数x的二进制位的最右侧的1:1100 -> 1000

x&(x-1)

x-1:将x的最右侧的1(包含该位)的右侧的二进制都取反,1左侧保持不变

x:1100   x-1: 1011

按位与后得就是删除最右侧1的效果。

8.位运算优先级

记不住就加括号

9.异或运算(^)的运算定律:

a^0 = a

a^a = 0(消消乐)

a^b^c  =  a^(b^c)

练习题:

136. 只出现一次的数字 - 力扣(LeetCode)

class Solution {public int singleNumber(int[] nums) {int n = nums.length;int ret = 0;for(int i=0;i<n;i++){//a^a = 0//a^0 = aret^=nums[i];}return ret;}
}

260. 只出现一次的数字 III - 力扣(LeetCode)

class Solution {public int[] singleNumber(int[] nums) {int ret=0;// 将数组中所有元素进行异或运算,最终结果中保存的就是那两个不同的数x1,x2 的异或结果for(int i=0;i<nums.length;i++){ret^=nums[i];}// 先找出最低位为1的位置,之所以为1,是因为x1,和x2的这一位的二进制位是不相同的,异或后才会是1int tmp=ret&(-ret);//获取到最低位为1的值// 可以将数组分成两部分: tmp位为1,tmp位为0int x1=0;//tmp位为0int x2=0;//tmp位为1// 将所有元素与tmp进行&运算://结果不为0的一组进行^运算,结果为0的进行^运算//(相同元素^运算,会相互抵消a^a=0,得到的就是那个只出现一侧的元素),for(int i=0;i<nums.length;i++){if((tmp&nums[i] )==0 ) x1^=nums[i];else x2^=nums[i];}return new int[]{x1,x2};}
}

191. 位1的个数 - 力扣(LeetCode)

class Solution {public int hammingWeight(int n) {int ret = 0;while(n!=0){if((n & 1)==1) ret++;n>>=1;}return ret;}
}

338. 比特位计数 - 力扣(LeetCode)

class Solution {public int[] countBits(int n) {int[] ret = new int[n+1];for(int i=0;i<=n;i++){int t = 0;for(int j=0;j<32;j++){if(((i>>j)&1)==1) t++;}ret[i] = t;}return ret;}
}

461. 汉明距离 - 力扣(LeetCode)

class Solution {public int hammingDistance(int x, int y) {int ret=0;for(int i=0;i<32;i++){// 获取最低位的二进制位int m=(x>>i)&1;int n=(y>>i)&1;if(m!=n) ret++;}return ret;}
}

371. 两整数之和 - 力扣(LeetCode)

class Solution {public int getSum(int a, int b) {//^ :无进位相加// &: 保存进位值// int a=a^b;// int b=(a&b)<<1;while(b!=0){int a1=a^b;int b1=(a&b)<<1;//(a&b)记录当前为是否需要进位,<<1:得到进位值a=a1;b=b1;}//b=0时,说明不需要进位了,a中保留的就是结果return a;}
}

137. 只出现一次的数字 II - 力扣(LeetCode)

统计每个数的第i二进制位为1的个数,然后%3,当不为0时,说明该二进制位的1是要求的数的二进制位累计的,将结果的该为置1.以次计算32位.得到结果

class Solution {public int singleNumber(int[] nums) {// 位运算解决int log=0;for(int i=0;i<32;i++){int ret=0; //注意:ret每次计算都要复原for(int j=0;j<nums.length;j++){ret+=((nums[j]>>i)&1);//获取所有元素二进制第i位的和// if(((nums[j]>>i) & 1)==1) ret++; }ret%=3;if(ret==1)  log|=(1<<i);}return log;}
}

面试题 17.19. 消失的两个数字 - 力扣(LeetCode)

260题的改版

class Solution {public int[] missingTwo(int[] nums) {int ret=0;for(int i=0;i<nums.length;i++){ret^=nums[i];ret^=(i+1);}int n=nums.length;ret^=(n+1);ret^=(n+2);//找到二进制中最低位的1的位置,从而将数组分成两类int tmp = ret&(-ret);int x1=0;int x2=0;for(int i=0;i<nums.length;i++){if((tmp&nums[i])==0) x1^=nums[i];else x2^=nums[i];}for(int i=1;i<=n+2;i++){if((tmp&i)==0) x1^=i;else x2^=i;}return new int[]{x1,x2};}
}
http://www.xdnf.cn/news/1375273.html

相关文章:

  • uniapp中 ios端 scroll-view 组件内部子元素z-index失效问题
  • 基于 Node.js 的淘宝 API 接口开发:快速构建异步数据采集服务
  • 汽车电气系统的发展演进为测试带来了哪些影响?
  • DeFi协议Lombard能突破比特币生态原生叙事困境吗?
  • 图表可视化地理趋势-Telerik WPF Chart
  • 【Day 35】Linux-主从复制的维护
  • (LeetCode 面试经典 150 题 ) 637. 二叉树的层平均值(深度优先搜索dfs)
  • 亚马逊广告关键词排名提升的五大核心策略解析
  • java简单ssm(spring+springmvc+mybatis)框架结构demo
  • 大模型重构建筑“能耗基因“:企业如何用物联中台打响能源革命?
  • 手写MyBatis第36弹:MyBatis执行流程中SQL命令类型解析
  • 登录业务——密码重置与强制修改初始密码实现思路
  • 【微信小程序】分别解决H5的跨域代理问题 和小程序正常不需要代理问题
  • Coze用户账号设置修改用户名-后端源码
  • map|math
  • 腾讯位置商业授权微信小程序路线规划
  • 【开源工具】基于Flask与Socket.IO的跨平台屏幕监控系统实战(附完整源码)
  • 前端性能优化:从指标监控到全链路落地(2024最新实战指南)
  • 论文阅读:Gorilla: Large Language Model Connected with Massive APIs
  • 深度学习入门:神经网络基础知识
  • lesson47:Linux常用软件使用指南:远程连接、远程拷贝、Vim与Nginx
  • VESA时序检测模块设计verilog实现
  • Ubuntu 24 Server 如何设置无线网络
  • imx6ull-驱动开发篇45——Linux 下 SPI 驱动框架简介
  • d435i相机读取镜头内参和相对之间的外参
  • 艾体宝新闻 | 98%好评率!KnowBe4 连续5年蝉联第一,现开放免费钓鱼测试等你解锁
  • 内网应用如何实现外网访问?外地通过公网地址访问内网服务器的设置方法
  • 遗传算法:模拟自然选择的优化智慧
  • Spring Boot项目集成日志系统使用完整指南
  • 欧洲数字化养殖平台 Herdwatch 借力 Iceberg + StarRocks 提升分析能力