【算法系列篇】位运算

在这里插入图片描述

文章目录

  • 前言
  • 什么是位运算算法
  • 1.判断字符是否唯一
    • 1.1 题目要求
    • 1.2 做题思路
    • 1.3 Java代码实现
  • 2. 丢失的数字
    • 2.1 题目要求
    • 2.2 做题思路
    • 2.3 Java代码实现
  • 3. 两数之和
    • 3.1 题目要求
    • 3.2 做题思路
    • 3.3 Java代码实现
  • 4. 只出现一次的数字
    • 4.1 题目要求
    • 4.2 做题思路
    • 4.3 Java代码实现
  • 5. 消失的两个数字
    • 5.1 题目要求
    • 5.2 做题思路
    • 5.3 Java代码实现
  • 总结

前言

位操作符想必大家都知道吧,&——按位与,|——按位或,^——按位异或,~——按位取法,位操作主要是用来操作二进制数的,就是因为它操作的是二进制,所以它的速度非常的快,那么既然他的速度很快,我们是否可以用位运算来解决一些实际问题呢?当然是可以的,这篇文章我将为大家分享如何使用位运算这种算法来解决一些问题。

什么是位运算算法

位运算算法是一组基于二进制位的操作符和操作方法的算法,用于在计算机中对二进制数字进行快速和高效的操作。位运算算法可以在二进制位级别上进行操作,包括位与(AND)、位或(OR)、位异或(XOR)、位取反(NOT)以及移位操作(左移和右移)等。

  • 按位与(&):只有当两个比特位都为1的时候结果才为1,否则为0
  • 按位或(|):两个比特位中有一个1,结果就为1
  • 按位异或(^):两个比特位相同为0,相异为1
  • 按位取反(~):除符号位之外,其它的比特位取反,为0结果为1,为1结果为0

位运算算法常用于以下情况:

  1. 位操作:可以通过位与、位或、位异或等运算符来对二进制数字的每一位进行操作,实现快速的位级别操作。
  2. 位掩码:可以使用位运算来创建和操作掩码,掩码经常用于标志位、权限控制和位字段的操作。
  3. 整数运算优化:位运算算法可以实现某些整数运算的高效实现,如乘以2的幂次方、除以2的幂次方、判断奇偶性等。
  4. 位图算法:位运算常用于位图算法,其中每个二进制位表示集合中的一个元素,可以进行高效的集合操作,如并集、交集、差集等。
  5. 压缩算法:位运算可以在压缩算法中起到重要的作用,用于压缩和解压缩数据,常见的例子包括哈夫曼编码和算术编码。

位运算算法通常具有高效性、简洁性和可移植性的特点,可以提供快速的底层操作,特别适合某些特定的问题和应用领域。在编写低级别的系统程序、嵌入式系统、网络协议和算法优化等方面,位运算算法发挥着重要的作用。

1.判断字符是否唯一

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

1.1 题目要求

实现一个算法,确定一个字符串 s 的所有字符是否全都不同。

示例 1:

输入: s = "leetcode"
输出: false 

示例 2:

输入: s = "abc"
输出: true

限制:

  • 0 <= len(s) <= 100
  • s[i]仅包含小写字母
  • 如果你不使用额外的数据结构,会很加分。
class Solution {public boolean isUnique(String astr) {}
}

1.2 做题思路

通常判断唯一性的时候,我们首先想到的是哈希表,但是这里限制我们不适用额外的数据结构,我们虽然可以使用数组来模拟哈希表,但这都不是最优解,这道题最优的解法就是使用位图的思想。为什么会选择使用位图呢?因为题目中说明了:字符串中只包含小写字母,也就是无重复字符的字符串的长度最长为26,而一个整型0有4个字节,32个比特位,并且二进制的0和1则恰好可以标志某一字符有或者没有。

那么如何使用位图的思想来解决这个问题呢?我们可以将每一个字符所代表的ASCII码值来表示它在32个比特位中的位置,用循环来遍历字符串中的每一个字符,如果该字符在32个比特位中的对应位置是0的话,则用 | 运算,将该位置变为1,如果该位置为 1 的话,则说明出现了重复的字符。

1.3 Java代码实现

class Solution {public boolean isUnique(String astr) {//鸽巢原理,当字符串长度大于26的时候一定会有重复的字符if(astr.length() > 26) return fasle; int tmp = 0; //tmp 代表32位比特位的位图for(int i = 0; i < astr.length(); i++) {char ch = astr.charAt(i);if(((tmp >> (ch - 'a')) & 1) == 1) return false;else tmp = tmp | (1 << (ch - 'a'));}return true;}
}

在这里插入图片描述

2. 丢失的数字

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

2.1 题目要求

给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

示例 1:

输入:nums = [3,0,1]
输出:2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,
因为它没有出现在 nums 中。

示例 2:

输入:nums = [0,1]
输出:2
解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2 是丢失的数字,
因为它没有出现在 nums 中。

示例 3:

输入:nums = [9,6,4,2,3,5,7,0,1]
输出:8
解释:n = 9,因为有 9 个数字,所以所有的数字都在范围 [0,9] 内。8 是丢失的数字,
因为它没有出现在 nums 中。

示例 4:

输入:nums = [0]
输出:1
解释:n = 1,因为有 1 个数字,所以所有的数字都在范围 [0,1] 内。1 是丢失的数字,
因为它没有出现在 nums 中。

提示:

  • n == nums.length
  • 1 <= n <= 104
  • 0 <= nums[i] <= n
  • nums 中的所有数字都 独一无二
class Solution {public int missingNumber(int[] nums) {}
}

2.2 做题思路

这道题目的意思就是,原本数组中的元素应该是[0,数组长度],但是数组中缺少了一个数字,我们需要找到这个缺失的数字。这个题有很多种解法:

  1. 哈希表。
  2. 高斯求和。将原本数组中的元素的和减去现有数组所有元素的和就得到缺失的那个数字
  3. 排序。将数组进行排序,然后遍历数组找到缺失的那个数字
  4. 位运算

能用位运算解决就尽量用位运算来解决,因为位运算的速度非常快,那么这道题如何使用位运算来解决呢?在这之前,我们需要知道,^ 操作,当两个相同的数字进行异或操作的时候结果为0,那么我们可以将原本数组中元素和现有数组中的元素都进行异或操作,相同的两个数异或结果为0,到最后异或的结果就是我们要找的那个缺失的数字。

2.3 Java代码实现

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

在这里插入图片描述

3. 两数之和

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

3.1 题目要求

给你两个整数 a 和 b ,不使用 运算符 + 和 - ​​​​​​​,计算并返回两整数之和。

示例 1:

输入:a = 1, b = 2
输出:3

示例 2:

输入:a = 2, b = 3
输出:5

提示:

  • -1000 <= a, b <= 1000
class Solution {public int getSum(int a, int b) {}
}

3.2 做题思路

两数之和,大家一看到这个题目可能就会觉得很简单,直接 return a + b; 不就行了吗?但是仔细看题目,这道题不允许使用运算符 + 和 -,那么如何在不使用运算符的情况下实现两数之和呢?位运算,通过位运算就可以在不适用运算符的情况下实现两数之和的运算。

当我们进行二进制的加法的时候,当两个比特位相加的结果为2的时候,就需要向前进一位,但是我们可以先使用 ^ 操作来进行无进位的加法,当两个比特位相加的结果为2时,不进行进位而得到的结果,然后再使用 & 操作,来得到什么时候该进位,然后将 & 的结果向左移动一位,将上面的两个结果再循环进行上面的操作,直到 & 得到的结果为0的时候,就得到了两数之和的结果。

在这里插入图片描述

3.3 Java代码实现

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

在这里插入图片描述

4. 只出现一次的数字

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

4.1 题目要求

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。

示例 1:

输入:nums = [2,2,3,2]
输出:3

示例 2:

输入:nums = [0,1,0,1,0,1,99]
输出:99

提示:

  • 1 <= nums.length <= 3 * 104
  • -231 <= nums[i] <= 231 - 1
  • nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
class Solution {public int singleNumber(int[] nums) {}
}

4.2 做题思路

通过题目,我们可以知道,除了那个只出现了一次的数字之外,其他的数字都出现了一次,所以呢,我们可以将数组中的每个元素的32个比特位分别相加,将结果 % 3,就会得到那个只出现一次的数字的对应比特位。
在这里插入图片描述

4.3 Java代码实现

class Solution {public int singleNumber(int[] nums) {int ret = 0;for(int i = 0; i < 32; i++) {int tmp = 0;for(int n : nums) {tmp += (n >> i) & 1;}ret |= (tmp % 3) << i;}return ret;}
}

在这里插入图片描述

5. 消失的两个数字

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

5.1 题目要求

给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗?

以任意顺序返回这两个数字均可。

示例 1:

输入: [1]
输出: [2,3]

示例 2:

输入: [2,3]
输出: [1,4]

提示:

  • nums.length <= 30000
class Solution {public int[] missingTwo(int[] nums) {}
}

5.2 做题思路

这个题目跟上面的消失的一个数字其实是类似的,只不过这里出现了两个消失的数字,我们不可能一次就找到两个消失的数字,但是我们可以分两次找。可以将这道题目转换为数组中只出现了一次的数字,这里大家可以看看我之前写过的一篇文章寻找单身狗,但是呢一个数组中只能找到一个只出现了一次的数字,如果要想找到两个只出现了一次的数字,我们可以将这两个消失的数组分别给分到两个不同的数组中,然后在每一个数组中找那个只出现了一次的数字,最终这两个消失的数字都会被找到。那么,如何将这两个消失的数字分在两个不同的数组中呢?同样是将原本的数组和现有的数组中的所有元素都进行异或操作,相同的元素异或为0,最后剩下的其实就是这两个消失的数字异或的结果,然后我们需要在这个异或的结果中找到比特位为 1 的位置,因为异或,相异为 1 ,相同为0,当找到这个为 1 的比特位之后,就可以将这些元素进行分组了,该比特位为 1 的为一组,为 0 的为另一组。

在这里插入图片描述

5.3 Java代码实现

class Solution {public int[] missingTwo(int[] nums) {int[] ret = new int[2];int tmp = 0;for(int n : nums) tmp ^= n;for(int i = 1; i <= nums.length + 2; i++) tmp ^= i;int flg = 0; //用来记录异或结果比特位为1的位置for(int i = 0; i < 32; i++) {if(((tmp >> i) & 1) == 1) {flg = i;break;}}for(int n : nums) {if(((n >> flg) & 1) == 1) ret[0] ^= n;else ret[1] ^= n;}for(int i = 1; i <= nums.length + 2; i++) {if(((i >> flg) & 1) == 1) ret[0] ^= i;else ret[1] ^= i;}return ret;}
}

在这里插入图片描述

总结

通过本篇博客,我们深入了解了位运算算法及其在计算机领域中的重要性和应用。位运算算法是一项强大的工具,它基于二进制位的操作,能够高效地处理二进制数据,提升程序的性能和效率。

在实际应用中,我们可以利用位运算算法来实现各种位级别的操作,如位掩码、位操作、整数运算优化、位图算法和压缩算法等。这些算法和技巧可以在底层系统编程、嵌入式系统、网络协议和算法优化等领域发挥重要作用。

然而,在使用位运算算法时,也需要注意一些优化技巧和注意事项。我们需要注意位运算的优先级、位移操作的性能和溢出问题,以及如何利用位运算进行快速乘法、除法和判断奇偶性等操作。深入理解这些技巧,能够更好地应用位运算算法,提高代码的效率和准确性。

位运算算法是计算机科学中一个广泛应用的领域,通过深入学习和实践,我们可以进一步探索和发现更多有趣的位运算技巧和应用。在日常编程中,合理运用位运算算法,能够帮助我们解决一些复杂的问题,实现更高效和可靠的程序。

希望本篇博客能够为读者提供一个全面而清晰的位运算算法入门指南,让大家对位运算算法有更深入的了解,并能够应用于实际开发中。通过不断学习和探索,我们可以进一步提升自己的编程能力,并在算法领域中取得更多的成就。

感谢您的阅读,希望本篇博客对您有所帮助。如果您有任何问题或反馈,欢迎留言交流。祝愿您在位运算算法的学习和应用中取得成功!

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

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

相关文章

Ansible项目实战管理/了解项目环境/项目管理

一&#xff0c;项目环境 1.项目基础 项目过程 调研阶段 设计阶段 开发阶段 测试阶段 运营阶段 2.项目环境 个人开发环境 公司开发环境 项目测试环境 项目预发布环境 灰度环境&#xff1a;本身是生产环境&#xff0c;安装项目规划&#xff0c;最终所有的生产环境都发…

Python框架【模板继承 、继承模板实战、类视图 、类视图的好处 、类视图使用场景、基于调度方法的类视图】(四)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

CUDA小白 - NPP(2) -图像处理-算数和逻辑操作(2)

cuda小白 原始API链接 NPP GPU架构近些年也有不少的变化&#xff0c;具体的可以参考别的博主的介绍&#xff0c;都比较详细。还有一些cuda中的专有名词的含义&#xff0c;可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》 常见的NppStatus&#xf…

解压jar包并导入库环境

背景 因为各种历史原因&#xff0c;当初的maven依赖环境已下载不了了&#xff0c;所以需要从生产环境的jar包里&#xff0c;获取库环境来本地运行。 但是网上很多方法都是用mvn install命令&#xff0c;一个个jar包导入的&#xff0c;不符合我的需求&#xff08;需要导入280多…

R语言APRIORI关联规则、K-MEANS均值聚类分析中药专利复方治疗用药规律网络可视化...

全文链接&#xff1a;http://tecdat.cn/?p30605 应用关联规则、聚类方法等数据挖掘技术分析治疗的中药专利复方组方配伍规律&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 方法检索治疗中药专利复方&#xff0c;排除外用中药及中西药物合用的复方。最近我们…

CSS3D+动画

CSS3D 1.css3D 给父元素设置 perspective:景深:近大远小的效果900-1200px这个范围内 transform-style:是否设置3D环境 flat 2D环境 默认值 perserve-3D环境 3D功能函数 1.位移: translateZ()translate3D(x,y,z) <!DOCTYPE html> <html lang"en"><h…

linux下载安装jdk

1.java安装unzip,zip yum install -y unzip zip 2.安装vim yum -y install vim* Linux-jdk1.8下载地址点击下载 jdk1.8-linux 提取码&#xff1a;h40h 1、将安装包上传至Linux服务器 2、创建安装文件夹 创建install mkdir -p /export/install3、解压到install文件夹中 tar…

13.搬砖

目录 题目 Description Input Output 思路&#xff08;归并排序&#xff09; 具体步骤如下 C整体代码&#xff08;含详细注释&#xff09; 归并排序总结 核心步骤 代码模板 题目 Description 小张在暑假时间来到工地搬砖挣钱。包工头交给他一项艰巨的任务&#xff0…

Royal TSX 6 Mac多协议远程软件

Royal TSX是一款功能强大的远程桌面管理软件&#xff0c;适用于Mac操作系统。它允许用户通过一个集成的界面来管理和访问多个远程计算机和服务器。 Royal TSX支持多种远程协议&#xff0c;包括RDP、VNC、SSH、Telnet和FTP等&#xff0c;可以方便地连接到Windows、Linux、Mac和其…

非煤矿山风险监测预警算法 yolov8

非煤矿山风险监测预警算法通过yolov8网络模型深度学习算法框架&#xff0c;非煤矿山风险监测预警算法在煤矿关键地点安装摄像机等设备利用智能化视频识别技术&#xff0c;能够实时分析人员出入井口的情况&#xff0c;人数变化并检测作业状态。YOLO的结构非常简单&#xff0c;就…

ios开发 swift5 苹果系统自带的图标 SF Symbols

文章目录 1.官网app的下载和使用2.使用代码 1.官网app的下载和使用 苹果官网网址&#xff1a;SF Symbols 通过上面的网址可以下载dmg, 安装到自己的mac上 貌似下面这样不能展示出动画&#xff0c;还是要使用动画的代码 .bounce.up.byLayer2.使用代码 UIKit UIImage(system…

解决报错Java: 非法字符: ‘\ufeff‘

方法一&#xff1a;直接remove BOM&#xff0c;再重新启动程序。 方法二&#xff1a;用notpad打开&#xff0c;点击编码为utf-8格式&#xff0c;保存。

GrapeCity Documents V6.0 Update 2发布,新增支持SpreadJS的.sjs文件格式

近日&#xff0c;GrapeCity Documents 正式迎来其V6.2 的发布更新&#xff0c;能够支持 SpreadJS 中 .sjs 类型的文件。这一重大更新将为用户带来更多地惊喜。 .sjs文件有两个关键优势&#xff1a;空间更小且导入导出速度更快。通过采用 .sjs格式&#xff0c;GcExcel实现了更高…

PO设计模式是selenium自动化测试中最佳的设计模式之一

Page Object Model&#xff1a;PO设计模式是selenium自动化测试中最佳的设计模式之一&#xff0c;主要体现在对界面交互细节的封装&#xff0c;也就是在实际测试中只关注业务流程就OK了传统的设计中&#xff0c;在新增测试用例之后&#xff0c;代码会有以下几个问题&#xff1a…

maven部署

一、下载Maven 地址&#xff1a;Maven – Download Apache Maven 二、解压缩&#xff0c;设置环境变量 tar -xvf apache-maven-3.8.8-bin.tar.gz export MAVEN_HOME/opt/apache-maven-3.8.8 export PATH$MAVEN_HOME/bin:$PATH echo $MAVEN_HOME echo $PATH mvn -v

Stable Diffusion Web UI的原理与使用

Stable Diffusion是一套基于Diffusion扩散模型生成技术的图片生成方案&#xff0c;随着技术的不断发展以及工业界对这套工程细节的不断优化&#xff0c;使其终于能在个人电脑上运行&#xff0c;本文将从github下载开始讲一讲如何使用Stable Diffusion Web UI进行AI图像的生成。…

水稻叶病害数据集(目标检测,yolo使用)

1.数据集文件夹 train文件夹&#xff08;44229张&#xff09;&#xff0c;test文件夹&#xff08;4741张&#xff09;&#xff0c;valid文件夹&#xff08;6000张&#xff09; 2.train文件夹展示 labels展示 标签txt展示 data.yaml文件展示 对数据集感兴趣的可以关注最后一行…

网络安全法+网络安全等级保护

网络安全法 2014年2月&#xff0c;中央网络安全和信息化领导小组成立&#xff0c;习主席当组长 2017年6月1日&#xff0c;网络安全法正式成立 网络安全是国家安全的重要组成部分没有网络安全就没有国家安全&#xff0c;没有信息化就没有现代化 网络安全法21条 网络安全法31条 …

[C/C++]天天酷跑游戏超详细教程-上篇

个人主页&#xff1a;北海 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C/C&#x1f91d;希望作者的文章能对你有所帮助&#xff0c;有不足的地方请在评论区留言指正&#xff0c;大家一起学习交流&#xff01;&#x1f9…

视频剪辑音效处理软件有哪些?视频剪辑软件那个好用

音效是视频剪辑的重要部分&#xff0c;能起到画龙点睛的作用。在短视频平台中&#xff0c;一段出彩的音效能将原本平平无奇的视频变得生动有趣。那么&#xff0c;视频剪辑音效处理软件有哪些&#xff1f;本文会给大家介绍好用的音效处理软件&#xff0c;同时也会介绍视频剪辑音…