C++算法 —— 位运算

一、基本的位运算操作

1.基础位运算操作符

<< : 二进制位整体左移

>> : 二进制位整体右移

~ : 按位取反

& : 按位与

| : 按位或

^ : 按位异或 (无进位相加)

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

(n >> x) & 1

3.将一个数n的二进制位第x位改成1

(1<<x) & n 

4.将一个数n的二进制位第x位改成0

(~(1<<x)) & n

5.位图的思想

位图就是一种利用比特位去承载信息的一种哈希思想,通常可以用来记录“在不在”等问题,利用32位比特位的一位或者多位去记录某种信息状态,和哈希表利用数组是一样的,位图是解决一些大基数的简单问题,具体操作这里不做详细整理

6.提前一个数(n)二进制位中最右边的1

n&(-n)

解释:因为-n就是将n的二进制先按位取反,然后再+1,例如:

原码:01100100
补码:10011011
反码:10011100

我们会发现将n变成-n之后,最右侧的1往后位置都保持不变,而1前面的位置的都相反,这是由于取反后又加1,前面部分不同因为取了反,后面因为加1进位,使得最右侧的1和原先的保持,所以n&(-n)可以提取最后一位1

7.干掉一个数(n)二进制位中最右边的1

n&(n-1)

这个太常见了,因为最后减1会相最右侧的1借位,所以n-1最右侧的1以后都会不同,而不影响前面

8.位运算的优先级

管它什么优先级,按自己的思路加括号!!!

9.异或运算的运算律

a^b^c = a^(b^c) ,即异或操作不在乎顺序

利用该性质有一个经典且量身定做的题目:只出现一次的数字 以及其变形  只出现一次的数字|||

因为太经典了,一搜就搜到了,简单提供下思路,只出现一次的数字,就是有一个数只有一个,其他都是成对出现的,因此只需要拿一个0去将这组数全部异或,最终结果就是那个只出现一次的数

而只出现一次的数字|||相对需要做一些处理,题目大致和原先一样,不过有两个只出现了一次的数字,其余都是出现两次的相同数,这个时候需要先将这组数据进行处理,还是利用异或去将这组数据进行分组,假如不同的那两个数是a和b,将a和b异或后,一定会有一个不等于0的数,我们拿到这个数最右侧的1位置去将数据分成两组数据,相同数据一定会被分到一组中,而那两个不同的数会被分到不同组中,此时问题就变回原先的模型了

二、判断字符是否唯一

1.链接

面试题 01.01. 判定字符是否唯一 - 力扣(LeetCode)

2.描述

3.思路

该题目若是不考虑额外的限制条件,则只需要使用哈希表,遍历字符串的同时若是遇到已经存在的字符则返回false,若是没有则存入字符到哈希表中,最终遍历结束后都没有重复则返回true

优化:题目要求若是不用额外的数据结构在面试中会很加分,我们可以使用位图的思想去完成,因为题目中提到只有小写字母,因此只有26种字符,所以直接用一个整形中的32bit位即可完成,思路上和哈希统计是没有区别的,只不过在使用位图的时候,更多的是通过位运算的操作,例如如果将某位变成1等等

4.参考代码

class Solution {
public:
    bool isUnique(string astr) 
    {
        if(astr.size() > 26) return false;
        int hash = 0;
        for(int i = 0;i<astr.size();i++)
        {
            int x = astr[i] - 'a';
            if( ( ( hash>>x )&1 ) == 0 ) 
                hash |= 1<<x;
            else
                return false;
        }
        return true;
    }
};

三、丢失的数字

1.链接

268. 丢失的数字 - 力扣(LeetCode)

2.描述

3.思路

这题的方法很多:哈希、二分法、数学方法、位运算

可以使用哈希表的方式去统计

也可以采用二分法,这和之前做过的一题点名很像

数学方法则是高斯求和,先将0到n的和算出来,然后减去数组和即可

位运算则是用异或的性质,将数组中所有数进行异或,然后再和0到n的数异或

4.参考代码

这里只提供一个位运算的代码参考,其他的都挺简单,可以自己尝试去写写

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

四、两数之和

1.链接

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

2.描述

3.思路

两数之和我们利用位运算中的按位异或,按位异或可以被看作为无进位相加,也就是说,只要处理好进位的问题,就可以实现相加,而进位可以通过按位与去得到那些部分需要进位

4.参考代码

class Solution 
{
public:
    int getSum(int a, int b) 
    {
        int ret = a^b;
        unsigned int up = a&b;
        while(up)
        {
            int tmp = ret^(up<<1);
            up = ret&(up<<1);
            ret = tmp;
        }
        return ret;
    }
};

五、只出现一次的数||

1.链接

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

2.描述

3.思路

4.参考代码

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int ret = 0;
        for(int i = 0;i<32;i++)
        {
            int bit = 0;
            for(auto x : nums)
            {
                bit +=((x>>i)&1);
            }
            bit%=3;
            if(bit == 1) ret |= (1<<i);
        }
        return ret;
    }
};

六、消失的两个数字

1.链接

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

2.描述

3.思路

这题的思路我们可以认为,是《消失的数字》+《只出现一次的数字|||》两个题目的合并,我们只需用一个0将【1,N】的数字都异或一次,再将数组里的数异或一次,就可以得到那消失的两个数的异或,再通过这个异或值对(【1,N】的数+数组的数)进行分组处理,分别用一个数去异或两组不同的数,最终得到的两个数就是消失的两个数

4.参考代码

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) 
    {
        int n = nums.size();
        int tmp = 0;
        for(auto x : nums) tmp^=x;
        for(int i = 1;i<=n+2;i++) tmp^=i;
        int a = 0;
        int b = 0;
        for(int i = 1;i<=n+2;i++)
        {
            if(i&(tmp&(-tmp)))
                a^=i;
            else
                b^=i;
        }
        for(auto x:nums)
        {
            if(x&(tmp&(-tmp)))
                a^=x;
            else
                b^=x;
        }
        return {a,b};
    }
};

总结

本篇章总结了关于位运算的相关经典算法,其中有几道面试常见题,虽然简单,但思路巧妙

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

聚类算法 | Kmeans:肘方法、Kmeans++、轮廓系数 | DBSCAN

目录 一. 聚类算法划分方式1. 划分式2. 层次式3. 基于密度4. 基于网络5. 基于模型 二. K-means算法1. K-means算法公式表达2. K-means算法流程3. Kmeans算法缺点3.1 肘方法3.2 k-means 算法3.2.1 k-means|| 算法 3.3 Mini Batch K-Means 算法 4. 聚类评估 三. DBSCAN算法1. DBS…

秋招学习数据库LeetCode刷题

数据库基本知识以前学过次数较多&#xff0c;今天看完一遍后都是可以理解的。直接刷Leetcode题吧 牛客上题库刷基础&#xff0c;Leetcode刷 写语句题(争取坚持每日2个sql语句题) 牛客&#xff1a;https://www.nowcoder.com/exam/intelligent?questionJobId10&tagId21015 L…

C#速览入门

C# & .NET C# 程序在 .NET 上运行&#xff0c;而 .NET 是名为公共语言运行时 (CLR) 的虚执行系统和一组类库。 CLR 是 Microsoft 对公共语言基础结构 (CLI) 国际标准的实现。 CLI 是创建执行和开发环境的基础&#xff0c;语言和库可以在其中无缝地协同工作。 用 C# 编写的…

私域必备神器来袭!朋友圈转发一键搞定!

在私域运营中&#xff0c;朋友圈的转发和管理是至关重要的环节。为了能够更好的管理和运营多个微信号的朋友圈&#xff0c;很多人都开始使用微信管理系统来辅助自己开展管理和运营工作。 接下来&#xff0c;就一起来看看微信管理系统的朋友圈管理功能吧&#xff01; 首先&…

π162U31 增强ESD功能,3.0kVrms隔离电压150kbps 六通道数字隔离器 可提高工业应用系统性能

π162U31产品概述&#xff1a; π162U31是一款数字隔离器&#xff0c;π162U31数字隔离器具有出色的性能特 征和可靠性&#xff0c;整体性能优于光耦和基于其他原理的数字隔离器 产品。 智能分压技术(iDivider技术)利用电容分压原理&#xff0c; 在不需要调制和解调的情况下&a…

【测试开发学习历程】python流程控制

前言&#xff1a;写到这里也许自己真的有些疲惫了&#xff0c;但是人生不就是像西西弗斯推石上山一样的枯燥乏味吗&#xff1f; 在python当中的流程控制主要包含以下两部分的内容&#xff1a; 条件判断 循环 1 条件判断 条件判断用if语句实现&#xff0c;if语句的几种格式…

【研发管理】产品经理知识体系-数字化战略

导读: 数字化战略对于企业的长期发展具有重要意义。实施数字化战略需要企业从多个方面进行数字化转型和优化&#xff0c;以提高效率和创新能力&#xff0c;并实现长期竞争力和增长。 目录 1、定义 2、数字化战略必要性 3、数字战略框架 4、数字化转型对产品和服务设计的影响…

京东云轻量云主机8核16G配置租用价格1198元1年、4688元三年

京东云轻量云主机8核16G服务器租用优惠价格1198元1年、4688元三年&#xff0c;配置为8C16G-270G SSD系统盘-5M带宽-500G月流量&#xff0c;华北-北京地域。京东云8核16G服务器活动页面 yunfuwuqiba.com/go/jd 活动链接打开如下图&#xff1a; 京东云8核16G服务器优惠价格 京东云…

截稿倒计时 CCF-B 推荐会议EGSR’24论文摘要4月9日提交

会议之眼 快讯 第35届EGSR 2024 (Eurographics Symposium on Rendering)即欧洲图形学渲染专题讨论会将于 2024 年 7月3日-5日在英国伦敦帝国理工学院举行&#xff01;在EGSR之前&#xff0c;将有一个全新的联合研讨会&#xff0c;即材料外观建模&#xff08;MAM&#xff09;和…

非机构化解析【包含PDF、word、PPT】

此项目是针对PDF、docx、doc、PPT四种非结构化数据进行解析&#xff0c;识别里面的文本和图片。 代码结构 ├── Dockerfile ├── requirements ├── resluts ├── test_data │ ├── 20151202033304658.pdf │ ├── 2020_World_Energy_Data.pdf │ ├── …

JVM字节码与类的加载——class文件结构

文章目录 1、概述1.1、class文件的跨平台性1.2、编译器分类1.3、透过字节码指令看代码细节 2、虚拟机的基石&#xff1a;class文件2.1、字节码指令2.2、解读字节码方式 3、class文件结构3.1、魔数&#xff1a;class文件的标识3.2、class文件版本号3.3、常量池&#xff1a;存放所…

【MATLAB源码-第181期】基于matlab的32QAM调制解调系统频偏估计及补偿算法仿真,对比补偿前后的星座图误码率。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在通信系统中&#xff0c;频率偏移是一种常见的问题&#xff0c;它会导致接收到的信号频率与发送信号的频率不完全匹配&#xff0c;进而影响通信质量。在调制技术中&#xff0c;QPSK&#xff08;Quadrature Phase Shift Keyi…

python打印杨辉三角形

杨辉三角形&#xff0c;这个在国外被叫做帕斯卡三角形&#xff0c;中华文明为何立于世界之颠&#xff0c;这个就是最好的证明&#xff0c;古人的杨辉至少是这个帕斯卡的鼻祖辈&#xff0c;比帕某早了393年发现&#xff0c;那时候可没有知识产权概率&#xff0c;不然就是妥妥的侵…

[尚硅谷 flink] 基于时间的合流——双流联结(Join)

文章目录 8.1 窗口联结&#xff08;Window Join&#xff09;8.2 **间隔联结&#xff08;Interval Join&#xff09;** 8.1 窗口联结&#xff08;Window Join&#xff09; Flink为基于一段时间的双流合并专门提供了一个窗口联结算子&#xff0c;可以定义时间窗口&#xff0c;并…

鲸鱼优化算法(Whale Optimization Algorithm)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法背景 鲸鱼优化算法&#xff08;Whale Optimization Algorithm, WOA&#xff09;是一种模拟鲸鱼捕食行为的优化算法。想象一下&#xff0c;你…

一文学会Semaphore(信号量)

// 空出来椅子 semaphore.release(count); } } catch (Exception e){ } } }; t.setName("Thread --> " i); t.start(); } } 程序将一直执行下去&#xff0c;不会漏单&#xff0c;也不会出现椅子占用数量大于20的情况。 AQS基础 Semaphore是一种共享锁&#xf…

若依框架mysql 搜索中文等于不生效

背景&#xff0c;字段存储的是中文 不生效代码如下 <if test"constellation ! null and constellation ! ">AND u.constellation #{constellation}</if> 正确生效的代码如下 <if test"constellation ! null and constellation ! ">A…

kubernetes集群添加到jumpserver堡垒机里管理

第一步、在kubernetes集群中获取一个永久的token。 jumpserver堡垒机用api的来管理kubernetes&#xff0c;所以需要kubernetes的token&#xff0c;这个token还需要是一个永久的token&#xff0c;版本变更&#xff1a;Kubernetes 1.24基于安全方面的考虑&#xff08;特性门控Le…

C语言自定义类型变量——结构体(二)

前言&#xff1a;上一篇内容中我们概述了结构体的基本内容&#xff0c;包括结构体的定义&#xff0c;声明&#xff0c;创建和初始化&#xff0c;内存对齐等问题&#xff0c;本篇将进一步深入结构体相关内容&#xff0c;包括为什么会存在内存对齐&#xff0c;结构体如何传参&…

【JavaWeb】Day35.MySQL概述——数据库设计-DDL(二)

表操作 关于表结构的操作也是包含四个部分&#xff1a;创建表、查询表、修改表、删除表。 1.创建 语法 create table 表名( 字段1 字段1类型 [约束] [comment 字段1注释 ], 字段2 字段2类型 [约束] [comment 字段2注释 ], ...... 字段n 字段n类型 [约束] [comment …