算法练习——位运算

ops/2024/12/28 4:59:08/

前言位运算的方法大多比较抽象,很难想到。

一:判断字符是否唯一

题目要求:

解题思路:

法一:使用hash的思想,统计每一个字母出现的次数,再通过一次循环遍历查询是否有超过1的字母,有就返回false,没有返回true

法二位运算(此处利用位图的思想)。字母一共只有26个,而一个int型整数有32个bit位,因此完全能够通过一个 int型整数的不同位 来充当hash表来统计每个字母出现的次数,想法和法一类似,只不过是通过位图的思想来实现

实现代码:

    bool isUnique(string astr) {int Bit_Count = 0;for(auto s : astr){if(((Bit_Count >> (s-'a')) & 1) == 1){return false;}else{Bit_Count |=(1<<s-'a');}}return true;}

二:丢失的数字

题目要求:

解题思路:

后续表达中:将丢失的数字 = 答案

思路:先将所有的数据异或,然后再将异或得到的结果与 0~n的所有数异或,最终得到答案。

之所以能够得到答案是因为,这两组数中,只有答案出现了一次,其他均出现了两次,而 a ^ a = 0,0 ^ b = b。

实现代码:

    int missingNumber(vector<int>& nums) {int n = nums.size();int tmp = 0;for(auto num : nums){tmp ^= num;}while(n){tmp^=n;n--;}return tmp;}

三:两整数之和

题目要求:

解题思路:

实现代码:

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

四:只出现一次的数字Ⅱ

题目要求:

解题思路:

后续表达中:将丢失的数字 = 答案

思路:数组的规律是:一个数出现3次,另一个数出现1次。那么就按bit位,通过for循环,记录32个bit位上,统计每位1出现的次数。

如果某位统计得到的1的个数为 0或3,说明该位不是答案的高位之一

如果某位统计得到的1的个数为 1或4,说明该位是答案的高位之一

:按照上述思路,可以写出任意一个出现n次的数和出现1次的数的代码。

实现代码:

    int singleNumber(vector<int>& nums) {int dest = 0;for(int i = 0; i<32; i++){int total = 0;for(auto s : nums){//统计每一位上1出现的次数if(((s>>i) & 1) == 1){total++;}}//若出现的次数%3 不为0 说明最终答案在该位上为高位if(total%3 == 1){dest |= (1<<i);}}return dest;}

五:只出现一次的数字Ⅲ

题目要求:

解题思路:

思路:以示例1为例,将所有数异或得到 3^5。再去查找 3^5 中 第一个1的位置diff,并记录下来,diff位上,3和5是的位数是不同的。然后我们再一次去异或这组数据,不过需要以diff位上是否为高位作为条件去异或,这样异或就把 3 5 拆分开来了,并最终得到答案。

实现代码:

    vector<int> singleNumber(vector<int>& nums) {int tmp = 0;//第一次异或得到 两个数的异或值for(auto s : nums){tmp ^= s;}int diff = 0;//循环找1,分了将两个数分开while(1){if(((tmp>>diff) & 1) == 1){break;}diff++;}//再次异或得到答案int a = 0;int b = 0;for(auto s : nums){if(((s>>diff) & 1) == 1){a^=s;}else{b^=s;}}return {a,b};}

六:消失的两个数字

题目要求:

解题思路:

后续表达中:将丢失的数字 = 答案1、答案2

此题结合了第二题与第五题的思路

思路:我们先按照第二题的思路,将所有数异或,因为数组包含1~N所有整数,所有我们再异或这1~N的所有整数,这样就得到了:答案1 ^ 答案2,此时这题就变成了第五题的样子,接下来的思路就和第五题完全一样了。

实现代码:

    vector<int> missingTwo(vector<int>& nums) {int tmp = 0;for(auto s : nums){tmp ^= s;}for(int i = 1; i<=nums.size()+2; i++) //+2是因为数组中只有两个数,又因为丢失两个数{                                     //所以总和是4tmp ^= i;}int diff = 0;while(1){if((tmp>>diff) & 1) break;diff++;}int a = 0;int b = 0;for(auto s : nums){if(((s>>diff) & 1) == 1) {a^=s;}else{b^=s;}}for(int i = 1; i<=nums.size()+2; i++){if(((i>>diff) & 1) == 1) {a^=i;}else{b^=i;}}return {a,b};}


http://www.ppmy.cn/ops/145574.html

相关文章

【uni-app】2025最新uni-app一键登录保姆级教程(包含前后端获取手机号方法)(超强避坑指南)

前言&#xff1a; 最近在配置uni-app一键登录时遇到了不少坑&#xff0c;uni-app的配套文档较为混乱&#xff0c;并且有部分更新的内容也没有及时更改在文档上&#xff0c;导致部分开发者跟着uni-app配套文档踩坑&#xff01;而目前市面上的文章质量也层次不齐&#xff0c;有的…

Binoculars——分析证实大语言模型生成文本的检测和引用量按学科和国家明确显示了使用偏差的多样性和对内容类型的影响

摘要 论文地址&#xff1a;https://www.biorxiv.org/content/10.1101/2024.03.25.586710v2.full.pdf 人工智能技术的进步正在改变数字内容生产和消费的格局。尤其值得注意的是生成式人工智能的快速发展&#xff0c;包括大规模语言模型&#xff0c;如 ChatGPT&#xff0c;它出现…

ffmpeg源码分析(九)解协议

本文将聚焦于FFmpeg协议处理模块&#xff0c;以avformat_open_input函数为核心&#xff0c;详细剖析其在最新FFmpeg源码中的实现。 音视频处理流程简介 avformat_open_input概述 avformat_open_input是FFmpeg用于打开输入多媒体数据的关键函数。它通过统一的接口处理多种协议…

嵌入式学习-QT-Day01

嵌入式学习-QT-Day01 Qt简介 1、Qt是什么&#xff1f; 2、新建项目 3、构建目录和工作目录 3.1、构建目录 3.2 工作目录 4、项目结构 4.1 项目配置文件.pro 4.2 用户文件.user 4.3 主文件 main.cpp 4.4 头文件dialog.h 4.5 源文件dialog.cpp 5、帮助文档 6、调试…

centos 释放系统预留内存并关闭Kdump服务

背景&#xff1a;Kdump是Linux系统的一种内核崩溃转储机制&#xff0c;它允许在系统发生内核崩溃&#xff08;例如内核panic&#xff09;时&#xff0c;捕获内存的转储信息&#xff0c;从而帮助事后分析故障原因。该过程需要一块预留内存&#xff08;称为crashkernel内存&#…

finalshell密码解密

finalshell密码解密 在线网站运行java https://c.runoob.com/compile/10/ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.N…

最优二叉搜索树【东北大学oj数据结构10-4】C++

题面 最优二叉搜索树是由 n 个键和 n1 个虚拟键构造的二叉搜索树&#xff0c;以最小化搜索操作的成本期望值。 给定一个序列 Kk1​,k2​,...,kn​&#xff0c;其中 n 个不同的键按排序顺序 &#xff0c;我们希望构造一个二叉搜索树。 对于每个关键 ki​&#xff0c;我们有一个…

基于Spring Boot的旅游推荐系统

一、系统背景与意义 随着旅游业的快速发展&#xff0c;旅游信息在种类和数量上不断增多&#xff0c;管理难度也在增大。基于Spring Boot的旅游推荐系统旨在解决这一问题&#xff0c;通过收集、处理和分析旅游数据&#xff0c;为用户推荐符合其偏好和需求的旅游线路&#xff0c…