【leetcode】位运算专题

news2024/11/15 11:09:21

文章目录

  • 1. 位1的个数
  • 2. 汉明距离
  • 3. 判定字符是否唯一
  • 4. 丢失的数字
  • 5. 两整数之和
  • 6. 只出现一次的数字Ⅱ
  • 7. 只出现一次的数字Ⅲ
  • 8. 消失的两个数字

在这里插入图片描述

首先我们先来复习一下几种位运算

  1. & 与:都为1,才为1
  2. | 或: 有1则1
  3. ^ 异或:相同为0,相异为1(无进位相加) n ^ 0 = nn ^ n = 0a ^ b ^ C == a ^ (b ^ c)
  4. ! 取反:按位取反,0变1,1变0

涉及到位运算,我们也要考虑位图的思想。

在这里我们也要给出两个位运算经常用的操作

  1. 提取一个数n二进制表示中最右侧的1
    n & - n
    在这里插入图片描述
    2. 删除一个数n二进制表示中最右侧的1
    n & (n-1)
    在这里插入图片描述

根据上面位运算的相关内容,我们就可以做下面的题目了

1. 位1的个数

在这里插入图片描述
题目链接

根据上面的描述,就是求一个数对应二进制位中1的个数。所以,我们可以使用 n & (n-1)来去除最右侧的1,直到该数变成0,就没有1了。去除了几次,就有几个1
在这里插入图片描述

int hammingWeight(int n) {
    int count = 0;
    while (n)
    {
        n &= n - 1;
        count++;
    }
    return count;
}

2. 汉明距离

在这里插入图片描述

题目链接

题目要求求两个数二进制位不同的个数,此时就可以使用 异或操作 得到不同的位,即可将题目转化为求一个数二进制位中1的个数。

在这里插入图片描述

    int hammingDistance(int x, int y) {
        int tmp = x ^ y;
        int count = 0;
        while(tmp)
        {
            tmp &= tmp - 1;
            count++;
        }
        return count;
    }

3. 判定字符是否唯一

在这里插入图片描述

  • 解法一:暴力遍历,“双指针”思想遍历,重复字符直接返回false。
  • 解法二:使用哈希表建立映射关系,遍历哈希表,有大于1的就返回false;否则返回true。
  • 解法三:采用位图的思想,使用26个比特位标记字符,如果当前遍历的字符其对应比特位为1了,说明有重复的字符,返回false;当前字符对应比特位为0,则之前没有出现过,当前出现了,比特位设置为1。
    (优化:字符串长度大于26,则一定有重复的,即“鸽巢原理”)

在这里插入图片描述

    bool isUnique(string astr) {
        if(astr.size() > 26)//优化
            return false;
        int bitset = 0;
        for(int i=0; i< astr.size(); i++)
        {
            //如果当前遍历字符出现过
            int t = astr[i] - 'a';
            if(((bitset >> t) & 1) == 1)
                return false;
            //当前遍历字符没有出现过,将该位设置为1,使其出现
            else  
               bitset |= 1 << t;
        }
        return true;
    }

4. 丢失的数字

在这里插入图片描述
题目链接

根据题目可知,数组中原本应该是[0,n] n+1个数,此时少了一个,要找到少的那一个。

  • 解法一:0-n求和,使用和再减去数组中的元素,和中最后剩余的数就是丢失的数字。
  • 解法二:根据异或运算的“交换律”,直接先将0-n异或起来,再异或数组中的元素,最后异或的结果就是丢失的数字。
    在这里插入图片描述
    int missingNumber(vector<int>& nums) {
        int num = 0;
        //先异或[0,n]
        for(int i=0; i <= nums.size(); i++)
            num ^= i;
        //再异或数组元素
        for(auto& e : nums)
            num ^= e;
        return num;
    }

5. 两整数之和

在这里插入图片描述
题目链接

题目要求不得使用+、-运算符,那我们只能从二进制位下手了。

两数的二进制位相加,每一位相加的结果无非就是1和0。是1时不存在进位;是0时可能存在进位。

那我们先将不进位的结果记录下来,也就是异或操作。然后再获得进位,两个数对应位都为1才会产生进位,所以让两数相与,即可获得要进位的位置。
在这里插入图片描述
在这里插入图片描述

    int getSum(int a, int b) {
        while(b)
        {
            int x = (a ^ b);// 无进位相加
            int y = (a & b) << 1;//记录进位
            a = x;
            b = y;
        }
        return a;
    }

6. 只出现一次的数字Ⅱ

在这里插入图片描述
题目链接

该题目类似于文章第三题

  • 解法一:暴力枚举
  • 解法二:使用哈希表,遍历完成后,哈希表中为1的就是目标元素
  • 解法三:使用位图的思想,由于每个数字都可用32个比特位来表示,我们可以通过遍历所有元素的第i个比特位,如果该比特位是1的元素的个数 count % 3 = = 1,则表明目标数和其余3*n个数该位置都为1,或者只有目标数该位置为1,那么就可以将该位置设置为1,当遍历完32位后,重新被设置的数就是目标数。

在这里插入图片描述

    int singleNumber(vector<int>& nums) {
        int num = 0;
        for(int i=0; i < 32; i++)
        {
            int count = 0;//记录当前比特位为1的个数
            for(auto& e : nums)
            {
                //当前元素的第i个比特位为1,记录个数
                if((e >> i) & 1 == 1)
                    count++;
            }
            if(count % 3 == 1) //要么 3*n+目标数 的该位为1,要么目标数该位为1
                num |= 1 << i;
        }
        return num;
    }

7. 只出现一次的数字Ⅲ

在这里插入图片描述
题目链接

  • 由于仅有两个数字出现了一次,那么所有数字相异或的结果就是两个仅出现一次数字异或的结果。
  • 异或的结果中为1的位就是二者不同的位,因此我们可以利用一个不同位将两者分开。
  • 其余出现两次的数该位一定相同,因此会被分到一边,对两边的数字各自异或,结果就是那两个仅出现一次的数。
    在这里插入图片描述
	vector<int> singleNumber(vector<int>& nums) {
        int sum = 0;
        //先将所有数异或再一起
        for(auto& e : nums)
            sum ^= e;
        //此时sum中就是两个仅出现一次的数异或的结果
        int t = 0;
        for(int i=0; i < 32; i++)
        {
            //寻找二者不同的一个二进制位
            if((sum >> i) & 1 == 1)
            {
                t = i;
                break;
            }
        }
        int x = 0, y = 0;
        //根据不同的二进制位将二者分开
        for(auto& e : nums)
        {
            if((e>>t) & 1 == 1)//第t位为1的分到一边
                x ^= e;
            else
                y ^= e;   //不为1的分到另外一边
        }
        return {x,y};
    }

8. 消失的两个数字

在这里插入图片描述
题目链接

该题目就是 (3.丢失的数字 + 7.只出现一次的数字Ⅲ) 的整合。

  • 首先,我们可以使用 [1,N] 与数组元素异或,异或的结果就是丢失那两个数据异或的结果。
  • 然后根据异或结果,找出两数字不同的一个二进制位
  • 通过和那一个不同的二进制位相&,将 [1,N] 与数组元素进行分类。分类后的结果就是每一边数字都出现了两次,仅两个丢失的数字出现了一次。

在这里插入图片描述

    vector<int> missingTwo(vector<int>& nums) {
        int sum = 0;
        int n = nums.size() + 2;
        //先异或[1,n]
        for(int i=1; i<= n; i++)
            sum ^= i;
        //再异或数组元素
        for(auto& e : nums)
            sum ^= e;
        //此时sum中就是两丢失数字异或的结果
        //找出两丢失数字一个不同的二进制位
        int t = 0;
        for(int i=0; i < 32; i++)
        {
            if(((sum >> i) & 1) == 1)
            {
                t = i;
                break;
            }
        }
        //根据这一个位,将[1,n]与数组元素进行分类
        int x = 0, y = 0;
        for(int i=1; i <= n; i++)
        {
            if(((i>>t) & 1) == 1)   x ^= i;
            else    y ^= i;
        }
        for(auto& e : nums)
        {
            if(((e>>t) & 1) == 1)   x ^= e;
            else    y ^= e;
        }
        return {x,y};
    }

在这里插入图片描述

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

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

相关文章

神经网络——优化器

1.优化器介绍&#xff1a; 优化器集中在torch.optim中。 Constructing it optimizer optim.SGD(model.parameters(), lr0.01, momentum0.9) optimizer optim.Adam([var1, var2], lr0.0001)Taking an optimization step for input, target in dataset:optimizer.zero_grad(…

Linux 基础技术介绍

Linux 是最著名和最常用的开源操作系统。作为一种操作系统&#xff0c;Linux 是位于计算机上所有其他软件之下的软件&#xff0c;接收来自这些程序的请求并将这些请求转发到计算机的硬件。 图1 Linux的发行版之一 Ubuntu 23.04 在许多方面&#xff0c;Linux 与您之前可能使用过…

超详细Git的基本命令使用(三)

&#x1f600;前言 本篇博文是关于Git的基本命令使用&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x1f60…

【第51课】前后台功能点文件下载文件读取文件删除目录遍历目录穿越

免责声明 本文发布的工具和脚本&#xff0c;仅用作测试和学习研究&#xff0c;禁止用于商业用途&#xff0c;不能保证其合法性&#xff0c;准确性&#xff0c;完整性和有效性&#xff0c;请根据情况自行判断。 如果任何单位或个人认为该项目的脚本可能涉嫌侵犯其权利&#xff0…

(C语言) stdlib 程序终止

文章目录 &#x1f4a3;前言&#x1f4a3;程序终止&#x1f9e8;EXIT_SUCCESS & EXIT_FAILURE&#x1f9e8;_Exit (C99)&#x1f9e8;exit & atexit&#x1f9e8;&#x1f9e8;exit&#x1f9e8;&#x1f9e8;atexit &#x1f9e8;quick_exit & at_quick_exit (C11…

config.h-config.cpp详解

config.h定义四种组合方式切换“ET LT” listenfd触发模式 ET LT connfd触发模式 ET LT LT是电平触发、ET是边缘触发。 level-triggered VS edge-triggered 电平触发&#xff1a;只要有就能触发。 边缘触发&#xff1a;从无到有才能触发。 以socket为例 可读&#xff1a;有数据…

Node 缓存、安全与鉴权

Node 缓存、安全与鉴权 1、Cookie1.1 Set-Cookie1.2 Cookie 的生命周期1.3 如何保证Cookie安全性1.4 Cookie 的作用域Domain 属性Path 属性 1.5 SameSite attribute1.6 JS操作Cookie1.7 安全性 2、 Node缓存2.1 缓存作用2.2 缓存类型强制缓存对比缓存&#xff08;协商缓存&…

ET6框架(三)前后端通讯分析

文章目录 一、信息的通讯二、网络通讯协议的“理像模型”三、网络通讯协议的“四层模型”四、什么是 Socket&#xff1f;五、Socket通讯流程 一、信息的通讯 网络消息的发送类似于邮寄信件的流程&#xff0c;需要一个地址及收件人。 在网络通讯中通常我们需要一个IP地址及端口…

P2709 小B的询问

*原题链接* 非常简单的莫队板子题&#xff0c;让我们求出区间[l,r]中每个数出现次数的平方和&#xff0c;设枚举到,原来答案是res&#xff0c;如果加上后&#xff0c;则原来的变为&#xff0c;即res相比原来加上&#xff0c;删除同理。知道如何维护一个数的添加和删除后&#…

录屏软件合集【收藏版】

嘎嘎好用 为了提高办公效率&#xff0c;满足办公需求&#xff0c;我已经整理到下面了↓↓↓想要的可以自拿喔&#xff01;自行领取吧

大模型本地化部署2-Docker部署MaxKB

大模型本地化部署2-Docker部署MaxKB 0、MaxKB简介1、安装docker2、在docker中拉取MaxKB镜像3、运行镜像4、访问MaxKB5、创建应用6、使用应用进行对话 0、MaxKB简介 MaxKB是一款基于LLM大预言模型的知识库问答系统。具有以下特点&#xff1a; 多模型支持&#xff1a;支持对接主…

Qt 调用执行 Python 函数

一.环境 Qt 5.15.2 python-3.12.5 二.安装 1.安装python-3.12.5.exe 三.配置 1.设置环境变量 2.设置Qt 编译环境 3.新建Python文件 4.运行 四.源码 1.修改pro文件 2.testPy.py 注意: .py文件需要拷贝到build目录下 def myPrint(string):print(string)def ad…

抖音ip会莫名其妙变成北京吗

‌‌抖音IP会莫名其妙变成北京吗&#xff1f;抖音的IP地址可能会莫名其妙变成‌北京‌&#xff0c;这通常是由于多种原因导致的&#xff0c;包括但不限于网络连接、用户使用的网络服务提供商等问题。以下是一些可能导致这种情况发生的原因和解决方法。 原因分析&#xff1a; 网…

mysql学习下

1&#xff1a;添加数据 1.1为表中所有字段添加数据 1.1.1NSERT 语句中指定所有字段名 语法&#xff1a;INSERT INTO 表名(字段名1&#xff0c;字段名2&#xff0c;…)VALUES(值1&#xff0c;值2&#xff0c;…); 例题&#xff1a;向student表中插⼊&#xff08;id为1&#…

src-登陆框的常见测试思路

常见的登陆形式 第三方平台 OAuth 认证 用户名 密码 手机号 短信验证码 邮箱 邮件验证码 登陆框的常见测试思路 弱口令 弱口令指的是人为设定、复杂度较低的密码口令 为系统账户&#xff08;尤其是管理员账户&#xff09;设置弱口令会使得整个系统的身份认证模块…

graalvm jenkins maven 配置

1. maven 使用指定jdk编译 设置 JAVA_HOME环境变量: linux: linux: export JAVA_HOME/data/java/graalvm-jdk-22.0.29.1window: set JAVA_HOMED:\develop\Java\graalvm-jdk-22.0.29.1 2.mvn编译报错 问题 : Unable to make field private final java.util.Comparator java.…

波束搜索算法图解【Beam Search】

许多 NLP 应用程序&#xff08;例如机器翻译、聊天机器人、文本摘要和语言模型&#xff09;都会生成一些文本作为其输出。此外&#xff0c;图像字幕或自动语音识别&#xff08;即语音转文本&#xff09;等应用程序也会输出文本&#xff0c;即使它们可能不被视为纯 NLP 应用程序…

#网络高级 笔记

modbus_tcp协议 modbus_rtu协议和modbus库 http协议和web服务器搭建 服务器原码分析和基于WebServer的工业数据采集项目 第H5&#xff0c;即网页制作&#xff0c;项目完善 一、modbus起源 1.起源 Modbus由Modicon公司于1979年开发&#xff0c;是一种工业现场总线协议标准 Mo…

Harmony(鸿蒙)使用之Bugly的简单使用

Bugly环境&#xff1a;Bugly Harmony 版本&#xff0c;支持Harmony OS Next平台 开发工具版本&#xff1a;DevEco Studio NEXT Developer Beta1&#xff08;以上&#xff09;&#xff0c;API 12 步骤一、创建产品&#xff0c;填写产品相关信息 1、注册完成后&#xff0c;可在…

R 语言学习教程,从入门到精通,R 绘图 中文支持(25)

1、R 绘图 中文支持 不同系统的字体库目录&#xff1a; Linux 一般在 /usr/share/fonts 下&#xff0c;我们可以使用 fc-list 命令查看&#xff1a; # fc-list /usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:styleBold /usr/share/fonts/truetype/de…