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

优选算法:位运算

位运算的一些基础概念

& :有0则为0

| :有1则为1

^ : 相同为0,相异为1;也可以称为无进位相加

>> << : 右移,左移

~:按位取反

一个数异或自己等于0,异或上0等于自己。

一个数取负数:n变为-n,要经过按位取反在加1。

提取最右侧的一个1:n&-n ,因为-n的本质是将最右侧的1的左侧全部变为和n相反的。

去掉最右侧的一个1:n&n-1 , 因为n-1需要最右侧的1来进行相减。

位图:就是将一个int的32位比特位看为一个数组,里面存储的东西就表示信息,这样就可能用一个变量就能解决。

判断字符是否唯一

算法思路

我们可以使用位图的思想,将字母映射到比特位上,其实只需要将字符串中的字母减去a,这样字符所对应到的数字就是0~26,我们只需要一个int类型的数字就可以处理了。当遍历到一个字母,我们就可以将其加入到位图中,判断一下这个位置是不是为1,如果是1就表示这个位置代表的数已经出现过,此时我们就直接返回false,是0的话就将这个比特位置为1,并继续遍历。

算法实现

public boolean isUnique(String astr) {if(astr.length()>26){return false;}int n = 0;for(int l = 0;l < astr.length();l++){int j = astr.charAt(l)-'a';if(((n>>j)&1)==1){return false;}else{ n|= 1<<j;}}return true;}}

丢失的数字

算法思路

这道题有多种实现,我们知道了数组的范围,就可以通过等差数列的求和公式求出总和,再将目标数组遍历求出总和,最后相减,就可以得到最后的结果。

但是我们也可以使用位运算的思路,将[0~n]的的数字都进行异或在一起,再将目标数组的所有数都一起异或,最后将两个数异或在一起,就可以得到缺失的那个数。

算法实现

 public int missingNumber(int[] nums) {int j = 0;for(int k = 0;k<nums.length+1;k++){j^=k;}int l = nums[0];for(int k = 1;k<nums.length;k++){l^=nums[k];}return j^l;}

两数之和

算法思路

前面说到^是无进位相加,那么我们只需要处理没有进位的情况就能实现相加的情况了。首先我们需要将两数进行^,此时得到了两数无进位的和,而进位的情况出现在两比特位都为1,此时使用&求出都为1的情况,然后将1右移一位,就可以得到进位的情况了,此时我们再将两个结果进行异或,但是可能出现进位一位之后又出现两个1相加的情况,此时就又需要重复上面的操作。直到两者&后的数为0。

算法实现

public int getSum(int a, int b) {while(b!=0){int c = a^b;int d = (a&b)<<1;a = c;b = d;}return a;}

出现一次的数字二

算法思想

可以看到这个数组中出现的元素第一个每一个比特位其实是3n*1+1,3n*0+1,3n*1+0,3n*0+0,这四种情况,那么此时我们将每一个数的每一个比特位单独拿出来进行统计,得到的总数%3,那么余数肯定是单独出现的那一个数的比特位的值,我们通过一个0来进行统计每一位的比特位,最后返回的肯定是单独出现一次的数字。

算法实现

public int singleNumber(int[] nums) {int ret = 0;for(int j = 0;j<32;j++){int sum = 0;for(int num:nums){sum+=((num>>j)&1);}if(sum%3==1){ret|=(1<<j);}}return ret;}

消失的两个数字

算法思路

其实我们可以看成是在一个数组中想寻找两个只出现一次的数,我们可以先将这个数组中的所有数^起来,就会得到这两个数异或的结果,然后根据异或的性质,找到第一个两个数不一样比特位,以此为分界将数组分为两个,这样最后两组中都会有一个单独出现一次的数,此时再将数组中的数根据这个不一样的比特位区分,异或,得到结果。

算法实现

  public int[] missingTwo(int[] nums) {int n = nums.length + 2;int num = 0;//处理创建的数组for(int k = 0; k<=n;k++)num^=k;//处理原数组for(int k:nums) num^=k;     //找到不同的一位int i = 0;while(true){if(((num>>i)&1)==1){break;}else i++;}int [] arr = new int [2];   for(int j = 0;j<nums.length;j++){if(((nums[j]>>i)&1)==1){arr[0]^=nums[j];}else{arr[1]^=nums[j];}}for(int j = 1;j<=n;j++){if(((j>>i)&1)==1){arr[0]^=j;}else{arr[1]^=j;}}


文章转载自:

http://Hsn6mCxx.pLzgt.cn
http://6Oxh8rx5.pLzgt.cn
http://lg2uafG5.pLzgt.cn
http://HBDMdGhZ.pLzgt.cn
http://LF4cO1Ua.pLzgt.cn
http://SOOeEOVf.pLzgt.cn
http://7RbdtNyP.pLzgt.cn
http://U8WgMxz6.pLzgt.cn
http://s1uPs2aF.pLzgt.cn
http://kGXYFnZK.pLzgt.cn
http://jX2uEoBb.pLzgt.cn
http://gTL5OplE.pLzgt.cn
http://tr2x1IF5.pLzgt.cn
http://twxa1T03.pLzgt.cn
http://5seUe8GX.pLzgt.cn
http://cseWS5ga.pLzgt.cn
http://mX3yryju.pLzgt.cn
http://RBBJT6J9.pLzgt.cn
http://Kkrb2sjn.pLzgt.cn
http://4Avzk56p.pLzgt.cn
http://3ja20mHj.pLzgt.cn
http://GKl7SrBP.pLzgt.cn
http://8E8JdEcS.pLzgt.cn
http://nTgJcyUM.pLzgt.cn
http://E6lKRGyC.pLzgt.cn
http://mPVwZJlJ.pLzgt.cn
http://r0I7vOpg.pLzgt.cn
http://08MJwrH5.pLzgt.cn
http://ZTZepXeY.pLzgt.cn
http://51b1bt7A.pLzgt.cn
http://www.dtcms.com/a/382352.html

相关文章:

  • 家宽上行限速的背后
  • 线性表---顺序表概述及应用
  • Custom SRP - Point and Spot Lights
  • 狂雨小说CMS内容管理系统 v1.5.5 pc+h5自适应网站
  • DeepSeek实战--自定义工具
  • 同位素分离
  • PID算法:从理论到实践的全面解析
  • 0x03-g a+b ib
  • 【Linux】初识Linux
  • Tomcat介绍与核心操作讲解(以Rhel9.3为例)
  • @RequiredArgsConstructor使用
  • 脉冲串函数在数字信号处理中的核心应用与价值
  • AI助力HTML5基础快速入门:从零开始理解网页结构
  • 大数据与财务管理专业如何转型做金融科技?
  • 【开题答辩全过程】以 高校实习信息管理系统为例,包含答辩的问题和答案
  • 贪心算法应用:推荐冷启动问题详解
  • “单标签/多标签” vs “二分类/多分类”
  • 多商户异次元发卡网是啥啊?
  • 使用 Anaconda Distribution 安装 Python + GDAL并在vscode配置开发环境(完整版)
  • 先进电机拓扑及控制算法介绍(3)——以“数据”驱动电机实现真正的无模型
  • 进程卡顿怎么办?Process Lasso 免费功能实测解析
  • Grafana配置连接时候证书与mongosqld启动证书的关系
  • XWiki Platform 路径遍历漏洞分析 | CVE-2025-55747CVE-2025-55748
  • Python快速入门专业版(二十九):函数返回值:多返回值、None与函数嵌套调用
  • DBSCAN 聚类:以“热闹”划界,任意形状成团,孤立点全当噪声
  • 设计模式:从Collections.synchronizedCollection()出发了解【装饰器模式】
  • CSS3的新特性
  • Python的包管理工具uv下载python版本慢问题解决
  • K8s学习笔记(二):Pod
  • 贪心算法应用:异常检测阈值调整问题详解