算法【Java】—— 位运算

news2024/9/23 14:07:58

位运算总结

位运算的运算符:按位与(&),按位或(|),按位异或(^),按位取反(~),还有移位操作符 <<,>>

确定一个数 n 的第 x 位是0 还是 1
(n >> x) & 1 等于 1 / 0 来进行判断

将 n 的第 x 位修改为 1
n |= (1 << x)

将 n 的第 x 位修改为0
n &= ~(1 << x)

提取 n 二进制最右侧的 1
n & -n

删除 n 二进制最右侧的 1
n & (n - 1)

异或运算的规律
a ^ a = 0
a ^ 0 = a
a ^ b ^ c = a ^ c ^ b (满足交换律)

位运算的优先级可以通过我们手动添加括号来解决,这样就可以减少我们的记忆负担了。

位图思想:和哈希表类似,只不过位图采用的是比特位标记的方式来记录数字。

实战演练

只出现一次的数字 Ⅰ

https://leetcode.cn/problems/single-number/

在这里插入图片描述


由于除了一个元素只出现一次,其他元素均出现了两次,所以我们可以将所有的数字进行异或运算,最后得到的结果就是只出现一次的元素。

class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for(int x : nums) {
            ans ^= x;
        }
        return ans;
    }
}

只出现一次的数字 Ⅲ

https://leetcode.cn/problems/single-number-iii/

在这里插入图片描述


假设最后的答案分别是 a ,b

按照上一道题目的思路,我们将所有的数字进行异或得到的结果为 a ^ b

现在我们需要将他们两个分开来,如何分开?首先这两个数字一定是不相同的,那么在某一个比特位上一定不同,我们找到这个不同的比特位,然后根据这个不同的比特位最为划分标准,将数组所有的元素分成两组,这两组再分别进行异或操作,最后就会得到 a 与 b 这两个数字。

如何找到不同的比特位?因为异或的无进位相加(相同的异或结果为0,相异的异或结果为1),所有只要能找到比特位为1,这个位置就可以作为后续的判断标准。这里我们就可以使用n & -n 获取n 最后一位的 1

class Solution {
    public int[] singleNumber(int[] nums) {
        int sum = 0;
        for(int x : nums) {
            sum ^= x;
        }

        sum &= -sum;
        int ret1 = 0, ret2 = 0;
        for(int x : nums) {
            if((x & sum) == 0) {
                ret1 ^= x;
            } else {
                ret2 ^= x;
            }
        }

        return new int[]{ret1,ret2};
    }
}

位 1 的个数

https://leetcode.cn/problems/number-of-1-bits/

在这里插入图片描述


直接使用 n & (n-1) 即可

class Solution {
    public int hammingWeight(int n) {
        int count = 0;
        while(n != 0) {
            n &= (n-1);
            count++;
        }
        return count;
    }
}

比特位计数

https://leetcode.cn/problems/counting-bits/

在这里插入图片描述

class Solution {
    public int[] countBits(int n) {
        int[] ans = new int[n+1];
        for(int i = 0; i <= n; i++) {
            int count = 0;
            int tmp = i;
            while(tmp != 0) {
                tmp &= (tmp - 1);
                count++;
            }
            ans[i] = count;
        }
        return ans;
    }
}

汉明距离

https://leetcode.cn/problems/hamming-distance/

在这里插入图片描述


计算不同的二进制位数,首先进行异或运算,然后计算这个结果有多少个 1 即可

class Solution {
    public int hammingDistance(int x, int y) {
        int sum = x ^ y;
        int count = 0;
        while(sum != 0) {
            sum &= (sum-1);
            count++;
        }
        return count;
    }
}

判定字符是否唯一

https://leetcode.cn/problems/is-unique-lcci/description/

在这里插入图片描述


这里我们首先会想到哈希表,但是如果不适用额外的数据结构,我们可以考虑位图,用一个变量上的比特位来记录数据,正好字符串都是小写字母,也就是26种字母,使用 26 个比特位就可以保存数据的状态。

class Solution {
    public boolean isUnique(String astr) {
        if(astr.length() > 26) { //鹊巢原理
            return false;
        }
        int bitSet = 0;//位图
        char[] arr = astr.toCharArray();
        for(char x : arr) {
            if((1 << (x-'a') & bitSet) != 0) {
                return false;
            } 
            bitSet |= (1 << (x-'a'));
        }
        return true;
    }
}

丢失的数字

https://leetcode.cn/problems/missing-number/description/

在这里插入图片描述


这道题可以使用等差数列求和公式来做

当然这里是位运算专题,我们可以使用为运算来做,首先我们可以将 0 ~ n 之间所有的数字进行异或运算,然后将数组里的所有数字和上一次异或的结果一起异或,这样就可以找到丢失的数字了。

class Solution {
    public int missingNumber(int[] nums) {
        int sum = 0;
        for(int i = 0; i <= nums.length; i++) {
            sum ^= i;
        }
        for(int x : nums) {
            sum ^= x;
        }
        return sum;
    }
}

两整数之和

https://leetcode.cn/problems/sum-of-two-integers/description/

在这里插入图片描述


我们知道异或运算可以得到无进位相加的结果,我们知道当两个比特位都为 1 进行相加的时候是需要进位的,所以我们可以通过两个操作数按位与再左移一位就可以知道哪一些比特位需要进行进位,再次重复上述操作,知道最后没有需要进位,就可以得到两个数字相加的结果。

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

只出现一次的数字 Ⅱ

https://leetcode.cn/problems/single-number-ii/description/

在这里插入图片描述


只有一个元素出现一次,其他元素均出现三次,那么我们可以进行比特位计数,计算每一位上所有的数字的 1 的个数,最后将结果 %3 ,就会得到只出现一次的元素的那一位比特位上是 1 还是 0.

一个整型数据由有32 个比特位,所以进行三十二次循环。

class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for(int i = 0; i < 32; i++) {
            int count = 0;
            for(int x : nums) {
                if(((1 << i) & x) != 0) {
                    count++;
                }
            }
            if(count % 3 == 1) {
                ans |= (1 << i);
            }
        }
        return ans;
    }
}

消失的两个数字

https://leetcode.cn/problems/missing-two-lcci/

在这里插入图片描述


这道题我们先将 1 ~ n 和数组所有的数字异或就可以得到消失的两个数字的异或结果(这里记为 a ^ b),现在就是分离他们了,很简单,和上面一样,找到最后的比特位为 1,以这个为标准开始划分,将 1 ~ n 和数组所有的元素都进行划分就可以得到最终的两个数字了。

class Solution {
    public int[] missingTwo(int[] nums) {
        int n = nums.length;
        int sum = 0;
        for(int i = 1; i <= n + 2; i++) {
            sum ^= i;
        }
        for(int x : nums) {
            sum ^= x;
        }

        sum &= -sum;
        int ret1 = 0, ret2 = 0;
        for(int i = 1; i <= n + 2; i++) {
            if((i & sum) != 0) {
                ret1 ^= i;
            } else {
                ret2 ^= i;
            }
        }
        for(int x : nums) {
            if((x & sum) != 0) {
                ret1 ^= x;
            } else {
                ret2 ^= x;
            }
        }
        return new int[]{ret1,ret2};
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

xinference linux系统下部署

1.创建虚拟环境 conda create -n xinfer pyrhon3.10 2.使用虚拟环境 conda activate xinfer (xinfer) roothome:~$ python -V Python 3.10.14 3.pip安装环境 pip install "xinference[all]" 4.启动服务 nohup xinference-local --host 0.0.0.0 --port 9997 &…

【数据结构】Java的HashMap 和 HashSet 大全笔记,写算法用到的时候翻一下,百度都省了!(实践篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

97、prometheus之yaml文件

命令回顾 [rootmaster01 ~]# kubectl explain ingressKIND: Ingress VERSION: networking.k8s.io/v1DESCRIPTION:Ingress is a collection of rules that allow inbound connections to reachthe endpoints defined by a backend. An Ingress can be configured to givese…

【超详细】基于YOLOv8训练无人机视角Visdrone2019数据集

主要内容如下&#xff1a; 1、Visdrone2019数据集介绍 2、下载、制作YOLO格式训练集 3、模型训练及预测 4、Onnxruntime推理 运行环境&#xff1a;Python3.8&#xff08;要求>3.8&#xff09;&#xff0c;torch1.12.0cu113&#xff08;要求>1.8&#xff09;&#xff0c…

网站建设中,sitemap是什么,有什么作用

在网站建设中&#xff0c;Sitemap&#xff08;站点地图&#xff09;是一种文件&#xff0c;通常采用txt或XML格式&#xff0c;它列出了网站中的网页、视频或其他文件的相关信息。Sitemap的主要作用是帮助搜索引擎更高效地抓取和索引网站内容。 以下是Sitemap的具体作用&#x…

ABAP 学习t-code DWDM

ABAP 学习t-code DWDM &#xff0c;里面有很多例子展示&#xff0c;且能看到源代码

【第十四章:Sentosa_DSML社区版-机器学习之时间序列】

目录 【第十四章&#xff1a;Sentosa_DSML社区版-机器学习时间序列】 14.1 ARIMAX 14.2 ARIMA 14.3 HoltWinters 14.4 一次指数平滑预测 14.5 二次指数平滑预测 【第十四章&#xff1a;Sentosa_DSML社区版-机器学习时间序列】 14.1 ARIMAX 1.算子介绍 考虑其他序列对一…

云计算第四阶段---CLOUD Day7---Day8

CLOUD 07 一、Dockerfile详细解析 指令说明FROM指定基础镜像&#xff08;唯一&#xff09;RUN在容器内执行命令&#xff0c;可以写多条ADD把文件拷贝到容器内&#xff0c;如果文件是 tar.xx 格式&#xff0c;会自动解压COPY把文件拷贝到容器内&#xff0c;不会自动解压ENV设置…

双十一快来了!什么值得买?分享五款高品质好物~

双十一大促再次拉开帷幕&#xff0c;面对众多优惠是否感到选择困难&#xff1f;为此&#xff0c;我们精心筛选了一系列适合数字生活的好物&#xff0c;旨在帮助每一位朋友都能轻松找到心仪之选。这份推荐清单&#xff0c;不仅实用而且性价比高&#xff0c;是您双十一购物的不二…

C++入门基础知识82(实例)——实例7【 判断一个数是奇数还是偶数】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 实例 【判断一个数是奇数还是偶数】相…

【JavaEE初阶】文件IO(上)

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 路径 绝对路径 相对路径 文件类型 文件的操作 File类 文件系统操作 创建文件,获取路径 删除文件 列出所有路径 路径修改 创建目录 mkdir和mkdirs 服务器领域,机械…

win系统接入google_auth实现动态密码,加强保护

开源代码地址&#xff1a;windows动态密码: 针对win服务器进行的动态密码管控&#xff0c;需要配合谷歌的身份认证APP使用 (gitee.com) 为什么要搞个动态密码呢&#xff1f; 首先云服务器启用了远程访问&#xff0c;虽然更换了端口以及初始用户名&#xff0c;不过还是是不是被…

go的结构体、方法、接口

结构体&#xff1a; 结构体&#xff1a;不同类型数据集合 结构体成员是由一系列的成员变量构成&#xff0c;这些成员变量也被称为“字段” 先声明一下我们的结构体&#xff1a; type Person struct {name stringage intsex string } 定义结构体法1&#xff1a; var p1 P…

老程序员的数字游戏开发笔记(三) —— Godot出你的第一个2D游戏(一篇文章完整演绎Godot制作2D游戏的全部细节)

忽略代码&#xff0c;忽略素材&#xff0c;忽略逻辑&#xff01; 游戏的精髓是人性与思想&#xff0c;我一篇一篇地制作&#xff0c;不想动手的小伙伴看一看就可以&#xff0c;感受一下也不错&#xff0c;我们是有目的性的&#xff0c;这一切都是为今后的AI融合打基础&#xf…

详解CORDIC算法以及Verilog实现并且调用Xilinx CORDIC IP核进行验证

系列文章目录 文章目录 系列文章目录一、什么是CORDIC算法&#xff1f;二、CORDIC算法原理推导三、CORDIC模式3.1 旋转模式3.2 向量模式 四、Verilog实现CORDIC4.1 判断象限4.2 定义角度表4.3 迭代公式 五、仿真验证5.1 matlab打印各角度的正余弦值5.2 Verilog仿真结果观察 六、…

大模型学习方向不知道的,看完这篇学习思路好清晰!!

入门大模型并没有想象中复杂&#xff0c;尤其对于普通程序员&#xff0c;建议采用从外到内的学习路径。下面我们通过几个步骤来探索如何系统学习大模型&#xff1a; 1️⃣初步理解应用场景与人才需求 大模型的核心应用涵盖了智能体&#xff08;AI Agent&#xff09;、微调&…

NodeFormer:一种用于节点分类的可扩展图结构学习 Transformer

人工智能咨询培训老师叶梓 转载标明出处 现有的神经网络&#xff08;GNNs&#xff09;在处理大规模图数据时面临着一些挑战&#xff0c;如过度平滑、异质性、长距离依赖处理、边缘不完整性等问题&#xff0c;尤其是当输入图完全缺失时。为了解决这些问题&#xff0c;上海交通大…

RK3588NPU驱动版本升级至0.9.6教程

RK3588NPU驱动版本升级至0.9.6教程 1、下载RK3588NPU驱动2、修改NPU驱动源码2.0 修改MONITOR_TPYE_DEV写错问题2.1 解决缺少函数rockchip_uninit_opp_table问题2.2 解决缺少函数vm_flags_set、vm_flag_clear的问题2.3 内核编译成功2.4 重新构建系统 3、注意事项4、其他问题处理…

故障诊断 | 基于双路神经网络的滚动轴承故障诊断

故障诊断 | 基于双路神经网络的滚动轴承故障诊断 目录 故障诊断 | 基于双路神经网络的滚动轴承故障诊断效果一览基本介绍程序设计参考资料效果一览 基本介绍 基于双路神经网络的滚动轴承故障诊断 融合了原始振动信号 和 二维信号时频图像的多输入(多通道)故障诊断方法 单路和双…

【原创】java+springboot+mysql党员教育网系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…