【LeetCode热题100】位运算

这篇博客先介绍了常见位运算操作,然后记录了关于位运算的几道题,包括判定字符是否唯一、丢失的数字、两整数之和、只出现一次的数字2、消失的两个数字。

在这一部分,我们不妨先来总结一下常见位运算操作:

1.基础位运算

>>是右移操作,<<是左移操作,~是按位取反,&是有0就是0,|是有1就是1,^有两种记忆方法1)相同为0,相异为1 2)无进位相加

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

我们约定,二进制的最右边为第0位,最左边为第31位,操作是(n>>x)&1,如果结果为0,那么第x位就是0,否则为1。

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

也就是第x位改为1,其它位保持不变,操作是 n  |=  (1<<x)

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

操作是  n &= (~(1<<x)) 

5.位图的思想

上面的2、3、4就是为位图来服务的,位图的本质是哈希表,让一个int的32个位的0/1来记录信息,利用2、3、4可以查看和修改位图。

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

先来说结果,操作是  n&-n。我们需要先来看一下-n的本质:

-n的本质是将最右侧的1,左边的区域全部变成相反,此时相&后,左边区域全部变成0,右边区域本来就是0,所以&完之后只剩下最右侧的1。

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

先来说结果,操作是  n&(n-1) ,我们需要看一下n-1的本质:让最右侧及其右边全变成相反,左侧不变,这样相&之后,左侧不变,右侧全部变成0,这就把最右侧的1干掉了。

8.位运算的优先级

能加括号就加括号。

利用上面这几条,我们就可以解决LeetCode中的191、338、461这三道题了,

9.异或^运算的运算律

1) a^a = 0(消消乐)

2) a^0 = a

3)a^b^c = a^c^b

class Solution {
public:
    bool isUnique(string astr) 
    {
        int bitmap = 0;
        for(auto e:astr)
        {
            int pos = e - 'a';
            if((bitmap>>pos) & 1) return false;
            bitmap |= (1<<pos);
        }
        return true;
    }
};

题目分析:这道题有很多种解法,这里我们学习两种方法:哈希表和位图。第一种,使用哈希表,遍历整个字符串,将字符串中的每个字符依次放到哈希表中并判断条件,这种方法的时间复杂度和空间复杂度都是O(N)。第二种,使用位图,使用一个int位图,0位表示'a',1位表示'b',依次类推,因此只需要用到0~25位,遍历整个字符串,修改对应的bit,bit位为0表示之前没遇到这个字符,bit位为0表示之前遇到过这个字符。

此外,我们还可以使用鸽巢原理(抽屉原理)进行优化,如果字符长度大于26,说明肯定有重复字符,直接返回false。

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

题目分析:这道题我们还是有很多思路的,包括哈希表、求和公式、异或运算。第一种,哈希表,将数组中所有数字依次放到哈希表中,然后看哈希表中缺失哪个数字。第二种,求和公式,计算出0~n之和,然后减去数组中的每个元素,剩下的就是缺失的元素。第三种,异或运算,将数组中每一个元素都异或到一起,然后再异或0~n中的每一个元素,结果就是缺失的数字。

class Solution {
public:
    int getSum(int a, int b) 
    {
        while(b != 0)
        {
            int x = a^b;// x是无进位相加的结果
            int carry = (a&b)<<1;// carry 是进位
            a = x;
            b = carry;
        }
        return a;
    }
};

题目分析:这种直接用加法求和,大概率是用位运算操作,我们画图来看一下具体方法,主要想法是,a^b是无进位相加,a&b<<1可以表示进位,当进位为0时,循环结束。

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int i = 0;
        int sum = 0;
        int ret = 0;
        while(i <= 31)
        {
            //找到所有数第i位相加的结果
            for(auto e : nums)
            {
                sum += (e>>i)&1;
            }
            if(sum % 3 == 1) ret |= 1<<i;
            sum = 0;
            i++;
        }
        return ret;
    }
};

题目分析:我们将nums中每个元素的某一位全部加到一起,总共有4中情况:3n个0+0、3n个0+1、3n个1+0、3n个1+1。无论哪种情况,都将加和结果%3,最后得到的0、1、0、1就是所求结果的每一个比特位。

扩展:我们可以把这一道题扩展到除了某个元素只出现一次,其他出现n次,只需在将每一位求和后%n即可。

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) 
    {
        int n = nums.size() + 2;
        int tmp = 0;
        //1.将所有数字异或到tmp上
        for(auto e : nums) tmp ^= e;
        for(int i = 1 ; i <= n ; i++) tmp ^= i;
        //2.找到a、b中的比特位的那一位
        int j = 0;
        for(j = 0 ; j < 32 ; j++)
        {
            if((tmp >> j) & 1) break;
        } 
        //3.按照tmp位分成两组
        int a = 0, b = 0;
        for(auto e : nums)
        {
            if((e >> j) & 1) a ^= e;
            else b ^= e;
        }
        //3.根据j位的不同,将所有的数划分为两类来异或
        for(int i = 1 ; i <= n ; i++)
        {
            if((i >> j) & 1) a ^= i;
            else b ^= i;
        }

        return {a,b};
    }
};

题目分析:这道题依然是用位运算的方式解决,第一步,先将nums中所有的数异或到同一个变量tmp上,然后再把1~N也异或到这个变量上,最后得到的就是缺失的两个数字的异或。第二步,找到tmp中,比特位为1的那一位。第三步,根据x位的不同,将nums中的数字划分成两组,将这两组分别异或到两个变量上,就可以得到缺失的两个数字。

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

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

相关文章

C++——模拟实现string

1.再谈string string为什么要被设计成模板&#xff1f;日常使用string好像都是char*&#xff0c;char*不够使用吗&#xff0c;为什么要设计成模板呢&#xff1f; 1.1 关于编码 //计算机的存储如何区分呢&#xff1f;int main() {//比如在C语言中&#xff0c;有整型//如果是有…

craco-less使用问题

craco-less使用问题 问题背景 前端是用React搭建&#xff0c;使用craco配置&#xff0c;相关库或插件版本如下 "craco/craco": "^7.1.0","react-scripts": "^5.0.1","craco-less": "^3.0.1"在生产环境&#xff…

P9235 [蓝桥杯 2023 省 A] 网络稳定性

*原题链接* 最小瓶颈生成树题&#xff0c;和货车运输完全一样。 先简化题意&#xff0c; 次询问&#xff0c;每次给出 &#xff0c;问 到 的所有路径集合中&#xff0c;最小边权的最大值。 对于这种题可以用kruskal生成树来做&#xff0c;也可以用倍增来写&#xff0c;但不…

国内可以使用的ChatGPT服务【9月持续更新】

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

SSM+vue音乐播放器管理系统

音乐播放器管理系统 随着社会的发展&#xff0c;计算机的优势和普及使得音乐播放器管理系统的开发成为必需。音乐播放器管理系统主要是借助计算机&#xff0c;通过对首页、音乐推荐、付费音乐、论坛信息、个人中心、后台管理等信息进行管理。减少管理员的工作&#xff0c;同时…

2024短剧系统开发,付费短剧小程序app源码教程,分销功能讲解搭建上线

短剧系统技术栈 前端&#xff1a;vue3uniapp 后端&#xff1a; php 数据库&#xff1a;mysql 服务器环境&#xff1a; centos7.6 宝塔 php7.4 MySQL5.7 一、短剧系统功能 短剧用户端&#xff1a; 小程序、抖音小程序、快手小程序、APP、 z付宝小程序 系统用户端详细功能&…

有关shell指令练习2

写一个shell脚本&#xff0c;将以下内容放到脚本中 在家目录下创建目录文件&#xff0c;dir dir下创建dir1和dir2 把当前目录下的所有文件拷贝到dir1中&#xff0c; 把当前目录下的所有脚本文件拷贝到dir2中 把dir2打包并压缩为dir2.tar.xz 再把dir2.tar.xz移动到dir1中 …

ABAP-Swagger 一种公开 ABAP REST 服务的方法

ABAP-Swagger An approach to expose ABAP REST services 一种公开 ABAP REST 服务的方法 Usage 1: develop a class in ABAP with public methods 2: implement interface ZIF_SWAG_HANDLER, and register the public methods(example method zif_swag_handler~meta) 3: …

nonlocal本质讲解(前篇)——从滤波到Nonlocal均值滤波

线性滤波 → \rightarrow →高斯滤波 → \rightarrow →高斯滤波 → \rightarrow →双边滤波 → \rightarrow →Nonlocal均值滤波 平均 高斯 双边 Nonlocal 目录 线性滤波高斯滤波双边滤波Nonlocal均值滤波 滤波最初是频域的概念&#xff0c;由于频域乘积对应空域卷积&am…

药物分子生成算法综述:从生成对抗网络到变换器模型的多样化选择

创作不易&#xff0c;您的打赏、关注、点赞、收藏和转发是我坚持下去的动力&#xff01; 基于已有的药物数据生成新的药物分子是一项复杂的任务&#xff0c;通常涉及到生成模型和机器学习算法。以下是一些常用的算法和方法&#xff1a; 1. 生成对抗网络 (GANs) 特点: 由生成…

罗马数字详解

一. 罗马数字の背景 1. 罗马数字的诞生与进化 罗马数字起源于古罗马帝国&#xff0c;拥有一个漫长而复杂的历史&#xff0c;始于公元前 8 世纪至 9 世纪&#xff0c;与古罗马帝国在帕兰丁山&#xff08;Palantine Hill&#xff09;周围建立的时间大致相同。不过&#xff0c;罗…

【GUI设计】基于Matlab的图像处理GUI系统(2),matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于Matlab的图像处理GUI系统&#xff08;2&#xff09;&#xff0c;用matlab实现。…

jboss

一。CVE-2015-7501 1.POC&#xff0c;访问地址 192.168.10.193:8080/invoker/JMXInvokerServlet 返回如下&#xff0c;说明接⼝开放&#xff0c;此接⼝存在反序列化漏洞 2.下载 ysoserial ⼯具进⾏漏洞利⽤ https://github.com/frohoff/ysoserial 将反弹shell进⾏base64编码…

java重点学习-设计模式

十三 设计模式 工厂模式&#xff1a;spring中使用&#xff08;目的是&#xff1a;解耦&#xff09; 1.简单工厂 所有的产品都共有一个工厂&#xff0c;如果新增产品&#xff0c;则需要修改代码&#xff0c;违反开闭原则是一种编程习惯&#xff0c;可以借鉴这种编程思路 2.工厂方…

基于SpringBoot+WebSocket实现地图上绘制车辆实时运动轨迹图

实现基于北斗卫星的车辆定位和轨迹图的Maven工程&#xff08;使用模拟数据&#xff09;&#xff0c;我们将使用以下技术&#xff1a; Spring Boot&#xff1a;作为后端框架&#xff0c;用来提供数据接口。Thymeleaf&#xff1a;作为前端模板引擎&#xff0c;呈现网页。Leaflet…

Java律师法律咨询小程序

技术&#xff1a;Java、Springboot、mybatis、Vue、Mysql、微信小程序 1.代码干净整洁&#xff0c;可以快速二次开发和添加新功能 2.亮点可以添加AI法律咨询作为 创新点 系统分&#xff1a;用户小程序端&#xff0c;律师web端和管理员端 用户可以在小程序端登录系统进入首…

c++249多态

#include<iostream> using namespace std; class Parent { public:Parent(int a){this->a a;cout << " Parent" << a << endl;} public:virtual void print()//在子类里面可写可不写 {cout << "Parent" <<a<&l…

机器翻译之Bahdanau注意力机制在Seq2Seq中的应用

目录 1.创建 添加了Bahdanau的decoder 2. 训练 3.定义评估函数BLEU 4.预测 5.知识点个人理解 1.创建 添加了Bahdanau的decoder import torch from torch import nn import dltools#定义注意力解码器基类 class AttentionDecoder(dltools.Decoder): #继承dltools.Decoder写…

大数据实验2.Hadoop 集群搭建(单机/伪分布式/分布式)

实验二&#xff1a; Hadoop安装和使用 一、实验目的 实现hadoop的环境搭建和安装Hadoop的简单使用&#xff1b; 二、实验平台 操作系统&#xff1a;Linux&#xff08;建议Ubuntu16.04或者18.04&#xff09;&#xff1b;Hadoop版本&#xff1a;3.1.3&#xff1b;JDK版本&…

安全热点问题

安全热点问题 1.DDOS2.补丁管理3.堡垒机管理4.加密机管理 1.DDOS 分布式拒绝服务攻击&#xff0c;是指黑客通过控制由多个肉鸡或服务器组成的僵尸网络&#xff0c;向目标发送大量看似合法的请求&#xff0c;从而占用大量网络资源使网络瘫痪&#xff0c;阻止用户对网络资源的正…