【算法】使用位运算解算法题(C++)

文章目录

  • 0. 位运算 基本介绍
  • 1. 位运算基本使用 + 连带题目
    • 191.位1的个数
    • 338.比特位计数
    • 461.汉明距离
    • 136.只出现一次的数字
    • 260.只出现一次的数字III
  • 2. 使用位运算解决算法题
    • 面试题01.01.判定字符是否唯一
    • 371.两整数之和
    • 137.只出现一次的数字II
    • 面试题17.04.消失的数字
    • 面试题17.19.消失的两个数字

0. 位运算 基本介绍

我们知道,一般基本位运算分为以下几种:

  1. & 按位与:有0则为0
  2. | 按位或:有1则为1
  3. ^ 按位异或:记法有2
    • 相同为0,相异为1
    • 不进位相加(00->0, 01->1, 11->0,相当于两数相加但不进位)
  4. ~ 按位取反:对操作数按位取反,即0变为1,1变为0。
  5. << 向左移动:相当于将其乘以2的若干次方
  6. >> 向右移动:相当于将其除以2的若干次方

1. 位运算基本使用 + 连带题目

当我们理解了基础位运算,我们要确保可以解决下图红字中的基本问题

在这里插入图片描述

在这里插入图片描述

通过上图设计的题目和思路,我们可以顺势解决以下几道题:


191.位1的个数

在这里插入图片描述

思路:

在这里插入图片描述

如图,我们只需要 将n的每一位都&1 即可:

  1. 将n&1,结果更新到ret
  2. n右移一位,持续此过程直到n为0

代码:

int hammingWeight(uint32_t n) {int ret = 0; // 记录结果while (n){ret += n & 1;n >>= 1;}return ret;
}

338.比特位计数

在这里插入图片描述

思路:

题目要求计算一个(1~n)范围内每个元素,二进制中1的个数

  1. 创建结果数组ret,变量count记录当前元素二进制中1的个数
  2. 将整个过程放到一个从0~n的循环中
  3. 计算当前元素位一的个数
  4. 将count给到ret,直至循环结束,返回ret

代码:

vector<int> countBits(int n) {vector<int> ret(n+1, 0);for(int i = 0; i <= n; ++i) // 统计0 ~ n中每个元素二进制位一的个数{int count = 0;int tmp = i;while(tmp) // 计算tmp中1的个数{count += tmp & 1;tmp >>= 1;}// 存储其1的个数ret[i] = count;}return ret;}

461.汉明距离

在这里插入图片描述

思路:

在这里插入图片描述

如图所示,我们知道异或相当于(相同为0,相异为1),只需要统计两数异或之后的结果中1的个数即就是不同位的个数,即汉明距离。

代码:

int hammingDistance(int x, int y) {int ret = 0;int tmp = x ^ y;// 异或后 1的个数 即为 二进制位不同位置数while(tmp){ret += tmp & 1;tmp >>= 1;}return ret;
}

136.只出现一次的数字

在这里插入图片描述

思路:

题目要求找到整数数组中只出现过一次的数字,此题可以用哈希表解题,但位运算的时间空间复杂度总体更为优秀。

  1. 我们知道,a ^ a = 0; b ^ 0 = b;
  2. 根据该思路,将数组所有元素异或,剩余元素即为只出现一次的

代码:

int singleNumber(vector<int>& nums) {int ret = 0;// 将全部元素异或,结果为只出现一次的数字for(int i : nums){ret ^= i;}return ret;
}

260.只出现一次的数字III

在这里插入图片描述

思路:

  1. 首先异或所有元素,得到tmp(所求两数的异或结果)
  2. 将tmp & -tmp 得到两元素的不同位differ
  3. 根据此不同位进行划分:
    • 如果当前元素num与differ按位与的结果不等于0,则a ^= num
    • 反之, b ^= num
  4. 最后a,b即为两个只出现一次的数字。

在这里插入图片描述

代码:

vector<int> singleNumber(vector<int>& nums) {int tmp = 0;for(int num : nums) tmp ^= num; // 全部元素异或// 防止溢出int differ = (tmp == INT_MIN ? tmp : tmp & (-tmp)); // 找a,b的不同位int a = 0, b = 0;for(int num : nums){	// 根据条件划分if((num & differ) != 0)a ^= num;elseb ^= num;}return {a, b};
}

2. 使用位运算解决算法题

上面的题是小试牛刀,下面的题正式进行位运算算法的代码编写。

面试题01.01.判定字符是否唯一

在这里插入图片描述

思路:

上题解法利用位图思想 :我们通过将字符串的每个元素存到int型变量bitMap中(该位为0:未出现过,为1:出现过),通过判断所有位是否有1则可判断字符串的字符是否唯一。

在这里插入图片描述

代码:

 bool isUnique(string astr) {// 位图if(astr.size() > 26)    return false;int bitMap = 0; // 从后向前存放字母的出现次数,0代表未出现过,1代表出现过for(char ch : astr){int i = ch - 'a'; // 取该字符位if((bitMap >> i) & 1 == 1)    return false; // 如果这一位存在,falsebitMap |= (1 << i);}return true;
}

371.两整数之和

在这里插入图片描述

题意很清晰:即不使用±运算符计算两个整数的和

思路:

我们知道:

  1. 按位异或^ = 不进位相加,而我们需要相加的结果,则只需要找到进位即可。
  2. 而(a & b)就是进位结果,但我们进位是向前一位进位,所以进位为(a & b) << 1。重复上述步骤,直到进位为0,就得到了最终结果。

代码:

int getSum(int a, int b) {while(b != 0){int nsum = a ^ b; // 不进位相加结果int carry = (a & b) << 1; // 进位数a = nsum;b = carry; // 重复步骤直到b==0}return a;
}

137.只出现一次的数字II

在这里插入图片描述
思路:

  1. 定义一个vector<int> count(32),用于存储nums中所有元素的二进制表示的各个位的出现次数;

  2. 对于记录完毕的count,count的每一位都有如下四种情况:
    在这里插入图片描述

    • 如图所示,即0, 1, 3n, 3n + 1四种情况
    • 而对这四种情况模3后结果有两种情况:0 和 1
  3. 将得出的结果还原到ret中(用|=还原)

代码:

int singleNumber(vector<int>& nums) {vector<int> count(32); // 存放数组所有元素的位for(int num : nums)for(int i = 0; i < 32; ++i) // 存{count[i] += (num >> i) & 1;}
// 遍历count中的32个元素,还原只出现一次的元素到ret中int ret = 0;for(int i = 0; i < 32; ++i){ret |= (count[i] % 3) << i;}return ret;
}

面试题17.04.消失的数字

在这里插入图片描述

思路:

我们知道:a ^ a = 0 且 0 ^ b = b ,则利用这个性质,将nums中的数与0~n的所有数异或,最终结果则为消失的数字。

代码:

int missingNumber(vector<int>& nums) {// 位运算int n = nums.size();int miss = 0;for(int i = 0; i < n; ++i) // 与数组所有元素and 0~n-1的元素异或{miss ^= i ^ nums[i];}miss ^= n; // 异或nreturn miss;
}

面试题17.19.消失的两个数字

思路:

“只出现一次的数字Ⅲ” 中有个思想就是通过两元素的不同位,进行划分,这里也是一样

  1. 异或所有数:得到缺失的两个数字的异或和
  2. 获取 tmp 中最右边为 1 的位数:找到两个缺失数字的不同位
  3. 根据 differ 的值,将数组元素划分为两组进行异或操作

代码:

 vector<int> missingTwo(vector<int>& nums) {int tmp = 0;int n = nums.size() + 2; // 数组中缺失两个数字,所以数组长度为n+2// 1. 异或所有数for (int i = 1; i <= n; ++i)tmp ^= i;for (int num : nums)tmp ^= num;// 2. 获取最右边为1的位数(不同位)int differ = tmp & -tmp;// 3. 根据differ,划分数组元素进行异或int a = 0, b = 0;for (int i = 1; i <= n; ++i) {if (i & differ)a ^= i;elseb ^= i;}for (int num : nums) {if (num & differ)a ^= num;elseb ^= num;}return {a, b};
}

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

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

相关文章

SDG大数据平台简介

联合国可持续发展目标&#xff08;Sustainable Development Goals&#xff09;缩写SDGs&#xff0c;是联合国制定的17个全球发展目标&#xff0c;在2000-2015年千年发展目标&#xff08;MDGs&#xff09;到期之后继续指导2015-2030年的全球发展工作。&#xff08;摘自百度&…

React学习计划-React16--React基础(八)react-redux使用与优化,纯函数介绍

笔记gitee地址 学习了 redux,为什么还要讲react-redux呢&#xff1f; redux不是专门为react所创建的,只不过在某一刻&#xff0c;react和redux看对眼了&#xff0c;所以俩人走到了一起&#xff0c;所以为了更好的支持redux,react官方出了react-redux来更好的支持redux 1. react…

Couchdb 垂直权限绕过漏洞(CVE-2017-12635)

一、漏洞描述 Apache CouchDB是一个开源数据库&#xff0c;专注于易用性和成为”完全拥抱web的数据库”。它是一个使用JSON作为存储格式&#xff0c;JavaScript作为查询语言&#xff0c;MapReduce和HTTP作为API的NoSQL数据库。应用广泛&#xff0c;如BBC用在其动态内容展示平台…

【Unity入门】UGUI之Slider(滑动条)

目录 一、什么是Slider&#xff1f;二、Slider属性与功能 一、什么是Slider&#xff1f; Slider控件允许用户可以通过鼠标来在预先确定的范围调节数值 我们可以在Hierarchy视图右键 -> UI ->Slider来创建滑动条 通过上图可以发现Unity内置的Slider主要有3部分&#x…

JAVA:面向对象1

类和对象 public String sayHello(){ //修饰符/ /返回值类型/ /方法名/ /方法的参数/ return "hello,world!"; return 返回值&#xff1b; } /* void 可以不写返回值&#xff0c;return一个空就行 &#xff1a; return; return 结束方法&#xff…

一些想法:关于行人检测与重识别

本文主要是介绍我们录用于 ECCV18 的一个工作&#xff1a;Person Search via A Mask-guided Two-stream CNN Model. 这篇文章着眼于 Person Search 这个任务&#xff0c;即同时考虑行人检测&#xff08;Pedestrian Detection&#xff09;与行人重识别&#xff08;Person Re-ide…

Vue:使用IDEA开发Vue的相关配置

一、IDEA无法识别.vue文件 1、IDEA 添加Vue插件 2、添加Vue配置 File | Settings | Editor | File Types 找到 HTML 文件 在下面点号 输入*.vue 二、IDEA无法创建.vue文件 1、问题 在开发过程中&#xff0c;发现创建文件的界面&#xff0c;没有vue模板 2、相关配置 Fi…

2024年01月IDE流行度最新排名

点击查看最新IDE流行度最新排名&#xff08;每月更新&#xff09; 2024年01月IDE流行度最新排名 顶级IDE排名是通过分析在谷歌上搜索IDE下载页面的频率而创建的 一个IDE被搜索的次数越多&#xff0c;这个IDE就被认为越受欢迎。原始数据来自谷歌Trends 如果您相信集体智慧&am…

基于JAVA的学校热点新闻推送系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 新闻类型模块2.2 新闻档案模块2.3 新闻留言模块2.4 新闻评论模块2.5 新闻收藏模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 新闻类型表3.2.2 新闻表3.2.3 新闻留言表3.2.4 新闻评论表3.2.5 新闻收藏表 四、系统展…

Mysql基础总结

一、MySql基础 MySQL常见面试题 一、索引相关 &#xff08;1&#xff09;什么是索引? 索引是一种数据结构&#xff0c;可以帮助我们快速的进行数据的查找。 &#xff08;2&#xff09;索引是个什么样的数据结构呢? 索引的数据结构和具体存储引擎的实现有关&#xff0c;…

vue中$nextTick作用和实例

为什么要使用nextTick&#xff1f; vue中DOM更新是异步执行&#xff0c;相当于我们在修改数据的时候&#xff0c;视图是不会立即更新的&#xff0c;会先把新的数据攒一赞&#xff0c;例如假如v-for更新这三个数据item1和item2和item3&#xff0c;按照vue的特性dom更新的特性会…

FPGA项目(13)——基于FPGA的电梯控制系统

1.摘要 随着科技的发展&#xff0c;电梯早在上个世纪就已进入人们的生活。对于电梯的控制&#xff0c;传统的方法是使用继电器——接触器控制系统进行控制。随着EDA技术的发展&#xff0c;FPGA已广泛应用于各项电子设计中&#xff0c;本设计即利用FPGA来实现对电梯控制系统的设…

助力打造智慧数字课堂,基于YOLOv7【tiny/l/x】开发构建教学课堂场景下学生课堂行为检测识别分析系统

近年来&#xff0c;随着行为检测技术的发展&#xff0c;分析学生在课堂视频中的行为&#xff0c;以获取他们的课堂状态和学习表现信息已经成为可能。这项技术对学校的教师、管理人员、学生和家长都非常重要。使用深度学习方法自动检测学生的课堂行为是分析学生课堂表现和提高教…

【LMM 006】LLaVA-Plus:可以学习如何使用工具的多模态Agent

论文标题&#xff1a;LLaVA-Plus: Learning to Use Tools for Creating Multimodal Agents 论文作者&#xff1a;Shilong Liu, Hao Cheng, Haotian Liu, Hao Zhang, Feng Li, Tianhe Ren, Xueyan Zou, Jianwei Yang, Hang Su, Jun Zhu, Lei Zhang, Jianfeng Gao, Chunyuan Li 作…

【大数据面试知识点】Spark的DAGScheduler

Spark数据本地化是在哪个阶段计算首选位置的&#xff1f; 先看一下DAGScheduler的注释&#xff0c;可以看到DAGScheduler除了Stage和Task的划分外&#xff0c;还做了缓存的跟踪和首选运行位置的计算。 DAGScheduler注释&#xff1a; The high-level scheduling layer that i…

大数据 - Hadoop系列《三》- HDFS(分布式文件系统)概述

&#x1f436;5.1 hdfs的概念 HDFS分布式文件系统,全称为:Hadoop Distributed File System。 它是一个文件系统&#xff0c;用于存储文件&#xff0c;通过目录树来定位文件&#xff1b;其次&#xff0c;它是分布式的&#xff0c;由很多服务器联合起来实现其功能&#xff0c;集…

(五)分文件编程

文章目录 为什么要引入分文件编程.C文件怎么添加.H文件怎么书写以及如何进行链接.H书写格式&#xff1a;“有头有尾标识符”例如&#xff08;timer.h) .H链接链接到头文件所在路径的文件夹路径即可 提供一个分文件编程的一种代码最后附上视频演示 为什么要引入分文件编程 C程序…

git的使用基础教程

最近项目在搞自动化测试&#xff0c;需要将各种测试脚本集成到自动化框架里边&#xff0c;这个就需要用到版本管理系统了,下面简单价绍一下git的使用。 首先从官网下载并安装git工具&#xff0c;下面以wins系统为例子说明 https://git-scm.com/downloads wins安装好后&#xff…

灸哥问答:软件架构在软件研发中的作用

软件架构在软件开发中扮演着至关重要的角色。我们在软件研发的过程中&#xff0c;类比于建造一座公寓楼&#xff0c;而软件架构就像是盖楼之前的设计图纸&#xff0c;如果没有设计图纸就直接盖楼&#xff0c;可想而知带来的后果是什么。我对软件架构的作用表现总结如下&#xf…

JS变量和函数提升

JS变量和函数提升 JS变量提升编译阶段执行阶段相同变量或函数 变量提升带来的问题变量容易不被察觉的遭覆盖本应销毁的变量未被销毁 如何解决变量提升带来的问题 JS变量提升 sayHi()console.log(myname)var myname yyfunction sayHi() {console.log(Hi) }// 执行结果: // Hi …