专题四_位运算( >> , << , , | , ^ )_算法详细总结

目录

位运算

常见位运算总结

1.基础位运算

2.给一个数 n ,确定它的二进制表示中的第 x 位是 0 还是 1

3.运算符的优先级

4.将一个数 n 的二进制表示的第 x 位修改成 1 

5.将一个数n的二进制表示的第x位修改成0

6.位图的思想

7.提取一个数(n)二进制表示中最右侧的 1 (lowbit)

8.干掉一个数(n)二进制表示中最右侧的 1

9.异或(^) 运算的规律

1. 判断字符是否唯⼀(easy)

解析:

1.暴力

2.位运算

总结:

2. 丢失的数字(easy)

解析:

1.暴力

2.位运算

总结:

3. 两整数之和(medium)

解析:

1.暴力:

2.位运算

总结:

4. 只出现⼀次的数字 II(medium)

解析:

1.暴力:

2.位运算:

总结:

5. 消失的两个数字(hard)

解析:

1.暴力:

2.位运算

总结:


位运算

常见位运算总结

1.基础位运算

  << : 数 n 的二进制左移x位                         按位与  &:有 0 就 0  (看&有没有很圆,长得很像0)

  >> : 数 n 的二进制右移x位                         按位或  | : 有 1 就 1  (看|  是不是长得很像1)

  ~  (按位取反,所有位0变1,1变0)          异或运算 ^ : 相同为0 ,相异为 1 / 无尽位相加 

eg:

2.给一个数 n ,确定它的二进制表示中的第 x 位是 0 还是 1

3.运算符的优先级

能加括号就加括号u,绝对不会错

4.将一个数 n 的二进制表示的第 x 位修改成 1 

5.将一个数n的二进制表示的第x位修改成0

那么就跟上一个思路一样,只要第x位,遇0,变0,即可。(&按位与)其他位全都&上一个1即可。

6.位图的思想

位图的思想其实就是哈希表

7.提取一个数(n)二进制表示中最右侧的 1 (lowbit)

n & (-n)  本质就是,得到最右侧的1,那么要考虑其他位都是于n 的每一位相反,但就是要保证最右侧的1,不变,然后&即可。

那么 (-n)就是先~(按位取反)再+1,就会让按位取反的1全都进位,变成0,知道遇到取反后的第一个0,变成1,就又变回了原来的1,然后再&即可。

8.干掉一个数(n)二进制表示中最右侧的 1

n & (n-1)  ,条件就是 n -1 就能一直向前借位,知道第一个不是0的1变成0.

再& ,就只会改变左边到借位这些位,全部都遇0,变0,到达删掉最右侧的1的效果 

9.异或(^) 运算的规律

1.a ^ 0 = a

2.a ^ a = 0 (消消乐)

3.a ^ b ^ c = a ^ (b ^ c)

^异或,再其数二进制的每一位上,相同为0,相异为1

那么就直接上例题:

1. 判断字符是否唯⼀(easy)

题目就是判断是不是字符串的字符是不是又重复的,但是不能借助任何数据结构,那么就可以考虑利用位运算,把字符当作比特位一样放在32位的数组里,如果有重复的,那么就可以利用比特位的0或1来判断。

解析:

1.暴力

不用多说,就是创建一个数组,来判断是否有字符的个数大于等于2,就返回false

2.位运算

利用一个int型32比特位来计算是否存在重复的字符,可以将字符s[i]-'a' 来存入这个32位里

class Solution {
public:bool isUnique(string astr) {int n=astr.size();if(n>26) return false;int bitMap=0;for(auto e : astr){int i=e-'a';//判断该字符是否存在过if((bitMap>>i)&1==1) return false;//如果不是,我就要把第i位改成1;bitMap |= (1<<i);}return true;}
};

总结:

用bitMap来创建一个相当于int型的数组,i来存储每一位字符该移动的位数,那么就将bitMap>>i移动i位后,在跟1进行按位与,如果第一位都是1,那么就会得到1,说明之前就重复存在过,返回false

只要没有返回false 说明都是第一次出现,那么就将他bitMap这一比特位进行改变为1 ,先将1<<左移i位后进行或等于。遇1就改变。

2. 丢失的数字(easy)

这题题目意思比较简单,就是数组范围是[0,n] 那么他们就缺少一个数字x,对于ret进行^异或计算,^异或有消消乐的能力,也有无进位相加,那么进行消消乐,最后有一个数没有被消掉,就可以直接返回。

解析:

1.暴力

不用多少,排序后对数组的每一个元素跟[0,n]进行比较,如果有有一个不相等,那么就返回这个i

2.位运算

利用^异或运算,将没有消掉的数字进行返回就ok

class Solution {
public:int missingNumber(vector<int>& nums) {int ret=0;for(auto e : nums) ret^=e;for(int i=0;i<=nums.size();i++) ret^=i;return ret;}
};

总结:

^异或运算, 具有消消乐和无进位相加,那么这题就利用了消消乐的性质,翻译过来其实就是找到只出现了一次的数字这个意思,将出现了两次的数字给消掉了

3. 两整数之和(medium)

不使用加减得到两数之和,那么就肯定考虑的是位运算,利用上一题提到的^,无进位相加,具有相加性质,那么就可以进行运算

解析:

1.暴力:

其实像这种都是简单的面试题,如果未来机式,管他3*7=21,都是直接return a+b;

2.位运算

利用^ 异或运算,进行无进位相加,那么相加的都是无进位的,然后将这个值赋值给a,在单独求进位,这个时候你会发现(a&b) 就全是进位,但是都是本该进位的值在原来的位,所以全都要进一位,就全都要进行<<1左移1位,在赋值给b,在重复进行(a^b),直到b无进位为止

class Solution {
public:int getSum(int a, int b) {while(b){int x=a^b;int jinwei=(a&b)<<1;a=x;b=jinwei;//知道进位为0}return a;}
};

总结:

本题利用^异或运算进行无进位相加,但是仍具有相加性质,只要在单独加上进位即可(只需要发现(a&b)全都是进位)

4. 只出现⼀次的数字 II(medium)

题目意思挺简单的,就是找数组中只出现了1次的数字,其他数字都出现了3次,那么就不能像上一题一样用^异或运算,消掉两个重复出现的数字,那么就会让数组全变成一个数字,那么就考虑其他位运算解决,本题有点难理解,还是要用心体会。

解析:

1.暴力:

用哈希表,每当把整个数组相同的数字都存到一起,最后返回只出现了一次的数字,有点麻烦了,时间复杂度高,空间复杂度也高

2.位运算:

我第一次写的时候听了好几遍视频,真的挺不好理解的。

class Solution {
public:int singleNumber(vector<int>& nums) {int ret=0;int n=nums.size();for(int i=0;i<32;i++){int sum=0;for(auto e : nums) if((e>>i)&1) sum++; //计算nums中所有数的第i位的和是多少if(sum%3) ret |= (1<<i);}return ret;}
};

总结:

首先就是再数组中找到只出现一次的数字,其他的数字都是出现三次,由于题目不让额外开辟新空间,那么就是说明只能利用位运算进行计算
那么就要思考从哪下手,比如记录一个整个数组的所有位,(每个数都含有32位,占4个字节),那么我们使用位运算,将整个数组的同一位进行相加,eg:第1位 有3n个1+0 -> 3n 或者  3n个0 + 0 -> 0  等4种情况,因为都是出现3次,那么就把记录这个位出现的次数%3 =0 或则1 ,这就证明ret 这个只出现一次的这个数字,这一位就是这个0 或者1,那么就改变ret这32位里面的这一位,知道遍历完整个数组的所有32位即可

5. 消失的两个数字(hard)

虽然这题是困难题,但是只要弄得前面的题目真很easy

解析:

1.暴力:

那就是用数组,任何一个个比较,但是违反了题意

2.位运算

就是前面几个题目的结合,理解位运算的本质,然后进行运用
方法一:sort时间复杂度不达标O(NlogN)>O(N),还可能退化到O(N^2)
O(N) 时间内只用 O(1) 的空间   就是位运算
在这种条件下,只有用位运算是最快,最节省空间的,并且很好想,就拿^ 异或运算来说,这个就相当于消消乐,因为nums数组里面全都是从1开始的数字,全部都^ 异或后,在对i从1开始到n+2个数字进行^
消除掉已经存在的数字,那么sum中记录的就是最后剩余的两个元素,即不纯在的两个数字,那么我们只需要找到一个已经消失的数字,那么再次与sum进行^ 就可以得到两个都不存在的数字
但是后面的测试用例可能不是完全有序,我就开始进行sort,这样就可以判断当nums[0]!=1的时候就可以判断出极端情况,直接得出有一个1不存在,那么就可以得到第二个不存在的数字,但是这样sort就会发现排序就花了O(NlogN) 况且当数组接近有序的时候,快排就退化到O(N^2) 所以还要进行优化
方法二:
优化:为了不排序,让时间复杂度跳到O(logN) 那么就是当tmp记录到只剩下消失的两个数字a,b那么就明白,当tmp32位里面有一位等于1的时候,就说明,在这一位上要么a==1,b==0 要么a==0,b==1 ,就是a与b在这一个比特位上绝对不同,那么就可以在1到n+2,这么多数里面进行^异或,只要在这一个比特位上数字为1的就把他^异或到a里,如果为0,就^异或到b里,然后在^异或数组nums里面的所有元素,那么a 和 b 就会被单独独立出来
class Solution {
public:vector<int> missingTwo(vector<int>& nums) {int tmp=0;for(auto e : nums) tmp^=e;for(int i=1;i<=nums.size()+2;i++) tmp^=i;//那么现在只剩下a,b,找出比特位不同的那一位int diff=0;while(1){if((tmp>>diff)&1) break;else diff++;} //根据diff位进行计算未出现的数字int a=0,b=0;for(int i=1;i<=nums.size()+2;i++){if((i>>diff)&1) a^=i;else b^=i;}for(auto e : nums){if((e>>diff)&1) a^=e;else b^=e;}return {a,b};}
};

总结:

就是从数组里面找出两个消失的数字,那么就考虑^异或运算,但是最后ret里面存的就是最后消失的两个数字,所以要将两个数分离。

1.就是找到一个已经消失的数,然后再进行^异或,就可以得到,但是数组要进行排序才行

2.不进行排序,那么ret里面有两个不同的数,那么并且已经进行^ 异或运算,相同为0,相异为1,当找到ret比特位有为1的时候就证明a与b已经有分离的办法,将数组里面所有再该位比特位为1的存入a,为0的存入b,然后再将每个数字进行^异或 就能完美的将a 与 b进行分离。

总结一下吧~位运算刚开始听的时候确实很吃力,也很难,但是当上面结论用多了,确实也很简单,正所谓熟能生巧,我的进步很大,希望对你也是~

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

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

相关文章

【嘉立创EDA】画PCB板中为什么要两面铺铜为GND,不能一面GND一面VCC吗?

在新手画板子铺铜时&#xff0c;经常会铺一面GND一面VCC。但一般情况下我们不会这样铺铜。下面将详细分析为什么要两面铺铜为GND&#xff0c;而不是一面GND一面VCC的原因&#xff1a; 提高散热能力 金属导热性&#xff1a;金属具有良好的导热性&#xff0c;铺铜可以有效分散PCB…

引用和指针的区别(面试概念性题型)

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;C知识点的补充_Jason_from_China的博客-CSDN博客 概念概述 内存占用&#xff1a; 引用&#xff1a;引用一个变量时&#xff0c;实际上并…

2024 年浙江省网络安全行业网络安全运维工程师项目 职业技能竞赛网络安全运维工程师(决赛样题)

2024年浙江省网络安全行业网络安全运维工程师项目 职业技能竞赛网络安全运维工程师&#xff08;决赛样题&#xff09; 应急响应&#xff1a;1 通过流量分析&#xff0c;找到攻击者的 IP 地址2 找到攻击者下载的恶意文件的 32 位小写 md5 值3 找到攻击者登录后台的 URI4 找到攻击…

攻防世界--->hackme

学习笔记。 下载 查壳。 64ida打开。 进入main&#xff1a; 跟进&#xff1a; 这是密文 咋一看这程序感觉很复杂&#xff0c;很复杂&#xff1a; 脚本&#xff1a; #include <stdio.h> #include <string.h> #include <stdlib.h>int main() {unsigned char …

【数据结构】线段树复杂应用

1.线段树离散化 逆序对 1.1逆序对 题目描述 猫猫 TOM 和小老鼠 JERRY 最近又较量上了&#xff0c;但是毕竟都是成年人&#xff0c;他们已经不喜欢再玩那种你追我赶的游戏&#xff0c;现在他们喜欢玩统计。 最近&#xff0c;TOM 老猫查阅到一个人类称之为“逆序对”的东西&…

小程序开发设计-第一个小程序:创建小程序项目④

上一篇文章导航&#xff1a; 小程序开发设计-第一个小程序&#xff1a;安装开发者工具③-CSDN博客https://blog.csdn.net/qq_60872637/article/details/142219152?spm1001.2014.3001.5501 须知&#xff1a;注&#xff1a;不同版本选项有所不同&#xff0c;并无大碍。 一、创…

5G Multicast/Broadcast Services(MBS) (二) Multicast

这篇是Multicast handling的overview,正文开始。 值得注意的是,对于5MBS multicast,UE只有处于RRC connected和Inactive时,网络侧才可以通过MRB将MBS multicast数据传输到 UE;处于Idle态只能进行MBS broadcast过程。 对于multicast涉及的RNTI有G-RNTI,G-CS-RNTI以及在RRC …

2022高教社杯全国大学生数学建模竞赛C题 问题二(1) Python代码

目录 问题 22.1 依据附件数据分析高钾玻璃、铅钡玻璃的分类规律数据类别编码不平衡数据处理分类模型决策树分类随机森林分类XGBoost分类LightGBM分类Catboost分类基于直方图的梯度提升Histogram-Based Gradient Boosting梯度提升树Gradient Boosting Tree逻辑回归Logistic朴素贝…

在linux用docker部署MySQL失败

Unable to find image mysql:latest locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp 128.121.243.107:443: i/o timeout. See docker run --help. 从网上找解决问题一直说是镜像问题&#xff0c;我原来的镜像是从自…

vue之我不会

一、计算属性 例子&#xff1a; 注意&#xff1a;调用计算属性时&#xff0c;不可以带括号&#xff0c;那样调用的就是方法&#xff0c;如&#xff1a;以下调用fullName时不可funnName() <div id"root">姓&#xff1a;<input type"text" v-model&…

spring ai整合ollama anythingllm

Windows安装ollama和AnythingLLM 下载安装包 下载上面的安装包ollama&AnythingLLM.zip 解压如下 安装ollama 双击OllamaSetup.exe安装即可&#xff0c;安装完成后再命令行查看 ollama --version 即安装成功 运行模型 常用的模型如下 我们选择常用的llama2 ollama r…

【Hot100】LeetCode—84. 柱状图中最大的矩形

目录 1- 思路题目识别单调栈 2- 实现⭐84. 柱状图中最大的矩形——题解思路 3- ACM 实现 原题链接&#xff1a;84. 柱状图中最大的矩形 1- 思路 题目识别 识别1 &#xff1a;给定一个数组 heights &#xff0c;求解柱状图的最大面积 单调栈 使用 Stack 来实现&#xff0c;遍…

wireshark打开时空白|没有接口,卸载重装可以解决

解决方法&#xff1a;卸载wireshark,全选卸载干净&#xff0c;重新安装旧版的wireshark4.2.7, 甚至cmd下运行net start npf时显示服务名无效&#xff0c;但打开wireshark仍有多个接口 错误描述&#xff1a; 一开始下载的是wireshark的最新版&#xff0c;win11 x64 在安装wir…

F28335 时钟及控制系统

1 F28335 系统时钟来源 1.1 振荡器OSC与锁相环PLL 时钟信号对于DSP来说是非常重要的,它为DSP工作提供一个稳定的机器周期从而使系统能够正常运行。时钟系统犹如人的心脏,一旦有问题整个系统就崩溃。DSP 属于数字信号处理器, 它正常工作也必须为其提供时钟信号。那么这个时钟…

几种mfc140u.dll常见错误情况,以及mfc140u.dll文件修复的方法

如果你遇到与mfc140u.dll 文件相关的错误&#xff0c;这通常指的是该mfc140u.dll文件可能丢失、损坏或与您的应用程序不兼容。详细分析关于mfc140u.dll文件错误会对系统有什么影响&#xff0c;mfc140u.dll文件处于什么样的位置&#xff1f;以下是几种常见的错误情况及其修复方法…

Chrome谷歌浏览器登录账号next无反应

文章目录 问题描述 我们的Chrome浏览器在更新之后&#xff0c;会出现登录谷歌账号的时候&#xff0c;当你输入你的谷歌邮箱之后&#xff0c;点击 n e x t next next,也就是下一步的时候&#xff0c;页面没有反应&#xff0c;也就是没有跳转到输入密码的页面。 分析 根据logs里…

vue3 透传 Attributes

前言 Vue 3 现在正式支持了多根节点的组件&#xff0c;也就是片段&#xff01; Vue 2.x 遵循单根节点组件的规则&#xff0c;即一个组件的模板必须有且仅有一个根元素。 为了满足单根节点的要求&#xff0c;开发者会将原本多根节点的内容包裹在一个<div>元素中&#x…

【数据结构】快速排序详解(递归版本)

目录 0. 前言 1. 快速排序的基本思想 2. 快速排序的不同版本的实现 2.1 hoare版本 2.1.1 单趟排序动图演示 2.1.2 递归展开多个子区间进行单趟排序 2.1.3 代码的具体实现 2.1.3.1 霍尔法单趟排序代码 2.3.1.2 霍尔法递归代码 2.2 挖坑法 2.2.1 单趟排序方法动图演示…

【数据结构】图的概念和存储结构

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C游记》《进击的C》《Linux迷航》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、图的概念二、图的存储结构2.1 邻接矩阵2.1.1 成员变量与默认成员函数2.1.2 GetIndex2.1.3 AddEdge2.1.4 Pr…

【设计模式-外观】

这里写自定义目录标题 定义UML图角色作用代码使用场景 定义 为子系统中一组相关接口提供一致界面&#xff0c;定义一个高级接口&#xff0c;使得子系统更加容易使用。 UML图 角色作用 外观&#xff08;Facade&#xff09;角色&#xff1a;这是外观模式的核心&#xff0c;它知…