leetCode-hot100-位运算专题

例题中的视频讲解是B站中的宝藏博主的讲解视频,每道题后面都附有该题对应的视频链接~

位运算知识总结

    • 1.异或
    • 2.与运算和或运算
    • 3.左移和右移
    • 4.综合例题

1.异或

参考资料:位运算-异或,以下知识点讲解的内容参考了该篇博文,有兴趣的伙伴可以去看看,讲的很详细。在知识点的后面加入了该知识点相关的例题,所有的例题都来自力扣-hot100,按照题号搜索题目即可。
概念
按位异或表示当两个二进制当前位相同则值为0,不同则为1
特点(重要!):
(1)0 异或 任何数 = 任何数(0^0=0,0^1=1
(2)1 异或 任何数 = 任何数取反 (1^0=1,1^1=0
(3)任何数 异或 自己 = 把自己置为0
常见用途
(1)实现特定位置的翻转
要将某个二进制数字的特定位置取反,可以让其与同位数的二进制数字异或,该二进制除了对应的特定位置为1,其他位置都为0(eg,将01011101的第2位和第3位取反,则可以与00000110异或)
(2)在不使用临时变量的情况下将两个数的值进行交换(a:10110110和b:00001101)

a = a ^ b
b = b ^ a
a = a ^ b

例题
136.只出现一次的数字
思路
本题用到了异或运算特点中(2)和(3):

  • 任何数异或自身等于把自己置为0 ->我们将数组中的所有元素异或,那么出现两次的元素全部变为0
  • 0异或任何数等于任何数 ->经过上个步骤的处理,数组中只有0和只出现一次的数字,异或后即可得到该元素。

视频讲解点击视频讲解-只出现一次的数字。
时间复杂度
时间复杂度为O(n)n为数组的长度。
代码实现

class Solution {public int singleNumber(int[] nums) {int ans = 0;for(int i = 0; i < nums.length;i++){ans = ans ^ nums[i];}return ans;}
}

268.丢失的数字
思路
本题和136题是相同的,将0~n的所有数字和数组元素异或,最后的结果即为结果,这里ans初始值设置为n,因为在循环中不包含n,数组的长度是n-1
时间复杂度
时间复杂度为O(n)n为数组的长度。
代码实现

class Solution {public int missingNumber(int[] nums) {int ans = nums.length;for(int i = 0; i < nums.length; i++){ans ^= nums[i] ^ i;}return ans;}
}

389.找不同
思路
本题的思路和268题类似,由于两个相同字符异或结果为 0,则 st 的全部字符异或之后就是 t 中添加的字符。其中由于 t 的长度比 s 大1,所以答案的初始值设置为 t 的最后一个字符。
时间复杂度
时间复杂度为O(n),其中n为字符串s的长度。
代码实现

class Solution {public char findTheDifference(String s, String t) {char c = t.charAt(t.length() - 1);for(int i = 0; i < s.length(); i++){c ^= s.charAt(i) ^ t.charAt(i);}return c;}
}

2.与运算和或运算

与运算和或运算比较简单,这里简单介绍一下
概念
与运算(&):两者都为1时结果为1,其余情况为0
或运算(|) :两者中有一个为1时结果为1,其余情况为0
使用场景
(1) n & (n - 1):用来判断一个数是否为2的幂,如果结果为0,则说明 n 是2的幂,否则不是,同时还可以统计一个数的二进制表示中有多少个1。
原理分析:
这个操作的原理是,对于一个2的幂,其二进制表示只有一个1,其余位都为0。而对于 n-1,其二进制表示中的最高位为0,其余位都为1。所以,当 nn-1 进行按位与操作时,如果结果为0,则说明 n 是2的幂,否则不是(eg. 8(1000) 和7(0111)按位与,结果为0,说明8的2
的幂)。
…待完善
例题
231.2的幂
思路
本题使用到的是使用场景中的(1)可以直接解决,需要注意的是0和负数不可能是2的幂,所以需要返回false
时间复杂度
时间复杂度为O(1),无论输入的n是多少,代码都只需要执行一次位运算操作即可判断n是否为2的幂次。
代码实现

class Solution {public boolean isPowerOfTwo(int n) {return n > 0 && (n & (n - 1)) == 0;}
}

3.左移和右移

概念
左移运算符m<<n表示吧m左移n位。左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。
右移运算符m>>n表示把m右移n位。右移n位的时候,最右边的n位将被丢弃。但右移时处理最左边位的情形要稍微复杂一点。这里要特别注意,如果数字是一个无符号数值,则用0填补最左边的n位。如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说如果数字原先是一个正数,则右移之后再最左边补n个0;如果数字原先是负数,则右移之后在最左边补n个1。
使用场景
(1)获取x的第k位:(x >> k) & 1
(2)将1或0添加到x的最后一位 :(x << 1) | 1或0
例题
190.颠倒二进制位
思路
使用左移和右移运算使用场景的(1)和(2),使用(n >> k) & 1取到n的第k位置,使用(x << 1) | 1或0将取到的第k位依次添加到答案中,视频讲解点击视频讲解-颠倒二进制位。
时间复杂度
时间复杂度为O(1),即常数时间复杂度。无论输入的n是多少,代码都需要执行32次循环。
代码实现

public class Solution {// you need treat n as an unsigned valuepublic int reverseBits(int n) {int ans = 0;for(int i = 0 ; i < 32; i++){ans = (ans << 1) | ((n >> i) & 1);}return ans;}
}

191.位1的个数
思路1
通过右移依次得到n的每一位,然后和1做与运算,如果为1则结果+1,反之+0,最后处理完n后即可得到结果值,视频讲解点击视频讲解-位1的个数。
时间复杂度
时间复杂度是O(1),因为循环次数固定为32次。
代码实现

class Solution {public int hammingWeight(int n) {int ans = 0;for(int i = 0; i < 32; i++){ans += (n >> i) & 1;}return ans;}
}

思路2
使用与运算中的使用场景中的第(1) n & (n - 1):统计一个数的二进制表示中有多少个1,每次执行 n & (n - 1)时都会消去n中的一位1,ans++,当n为0时及n中的1被全部消掉,此时ans即为所求。
时间复杂度
时间复杂度为O(logn),其中n表示给定的整数n的位数。代码中的while循环会执行的次数取决于n的二进制表示中1的个数,而一个整数n的二进制表示中1的个数最多为logn,因此时间复杂度为O(logn)
代码实现

class Solution {public int hammingWeight(int n) {int ans = 0;while (n > 0) {n &= (n - 1);ans++;}return ans;}
}

4.综合例题

318.最大单词长度乘积
思路
本题使用位运算的思想来判断两个字符串是否包含相同的字符。首先,创建一个大小与words数组长度相同的整数数组bitWords。然后,遍历words数组,将每个字符串转换为一个整数,用于表示该字符串包含的字符。具体地,对于每个字符串,将其中的每个字符与'a'做差,然后将结果作为二进制位的索引,将相应的位设置为1。这样,整数bitWords[i]就表示了words[i]字符串包含的字符。
接下来,使用两层循环遍历所有的字符串对,并通过位运算判断它们是否包含相同的字符。具体地,计算两个字符串长度的乘积,并将乘积与ans进行比较,更新ans的值。当且仅当两个字符串对应的整数按位与的结果为0时,说明它们不包含相同的字符。最后,返回ans作为结果。
时间复杂度
时间复杂度为O(n^2 * m),其中nwords数组的长度,m是单词的平均长度。
代码实现

class Solution {public int maxProduct(String[] words) {int[] bitWords = new int[words.length];for(int i = 0; i < words.length; i++){bitWords[i] = 0;for(int j = 0;j < words[i].length(); j++){bitWords[i] |= 1 << (words[i].charAt(j) - 'a'); }}int ans = 0;for(int i = 0;i < words.length;i++){for(int j = i;j < words.length;j++){int temp = words[i].length() * words[j].length();if((bitWords[i] & bitWords[j]) == 0) {ans = Math.max(temp,ans);}}}return ans;}
}

78.子集
思路2二进制法
由于数组中无重复元素,那么我们可以用二进制的位数来表示数组中的元素(n个元素即二进制为2^n,它的子集有2^n个),我们知道二进制是0和1的组合,当某一位为1时说明该位置对应的元素被选择了,由于二进制包含所有的组合,所以将0-2^n中所有的二进制数按照上述规则对应成子集,每一个二进制数字对应一个子集(对应位置为0即不选择,对应位置为1即选择),则可以得到子集的全集,视频讲解点击视频讲解-子集,视频中有详细的模拟举例。
时间复杂度
这段代码的时间复杂度为O(2^n * n),其中n为数组nums的长度。这是因为对于nums数组的每个元素,都有可能在子集中存在或不存在,所以一共有2^n种可能的子集组合,并且在每一种可能中,需要花费O(n)的时间来生成子集。因此,整体的时间复杂度为O(2^n * n)
代码实现

class Solution {public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> ans = new ArrayList<>();int n = nums.length;for(int mask = 0;mask < (1 << n); mask++){List<Integer> subset = new ArrayList<>();for(int i = 0; i < n; i++){//(mask & (1 << i)) != 0表示索引为i的位置对应的mask二进制为1,所以将nums[i]加进subsetif((mask & (1 << i)) != 0) subset.add(nums[i]);}ans.add(new ArrayList<>(subset));}return ans;}
}

在LeetCode-hot100题解—Day7中还介绍了深度优先遍历的解决方法,相比于上述解法更加高效一点。
137.只出现一次的数字 Ⅱ
思路
使用位运算来统计每个位上数字出现的次数,然后根据出现次数是否为3的倍数来确定只出现一次的数字在该位上的值。最后,将每个位上的值组合起来就得到了只出现一次的数字。简单来说,就是将每个数组元素用二进制表示,然后算出每个数组元素对应位置上1的总数,如果这个数字出现了三次,那么该位的1的个数是3的倍数,如果不是3的倍数,则将该位设置到结果中,举个栗子:
在这里插入图片描述

时间复杂度
时间复杂度为O(n),其中n是数组的长度。
代码实现

class Solution {public int singleNumber(int[] nums) {int ans = 0;for(int i = 0; i < 32;i++){int cnt = 0;for(int num : nums){cnt += (num >> i) & 1;}if(cnt % 3 != 0) ans |= (1 << i);}return ans;}
}

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

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

相关文章

基于Python实现蔬菜水果识别

蔬菜水果识别在农业生产、食品加工和市场销售等领域具有重要意义。随着计算机视觉和机器学习技术的发展,利用图像识别技术实现蔬菜水果的自动化识别已成为可能。 目录 引言研究背景问题陈述研究目标文献综述蔬菜水果识别的相关研究概述基于计算机视觉和机器学习的图像识别方法…

HCIP的学习(17)

BGP基础配置 使用直连接口IP地址来建立EBGP对等体关系 1、启动BGP协议 [r1]bgp 100 ----启动BGP协议&#xff0c;并且规定其AS号2、配置设备的RID数值&#xff0c;一般选择设备的loopback接口的IP地址 [r1-bgp]router-id 1.1.1.13、配置BGP对等体信息&#xff0c;包含了对等体…

K8s源码分析(一)-K8s调度框架及调度器初始化介绍

本文首发在个人博客上&#xff0c;欢迎来踩&#xff01; 文章目录 调度框架介绍K8s scheduler 介绍K8s scheduler的初始化Cobra介绍K8s scheduler中初始化的源代码解析 调度框架介绍 这是官方对于v1.27调度框架的介绍文档&#xff1a;https://v1-27.docs.kubernetes.io/docs/…

AR系列路由器配置本地同一网段互通

A R 路由器是华为公司推出的企业级路由器产品系列&#xff0c;具有高可靠性、高性能和易管理等特点。AR 系列路由器提供的功能包括路由转发、安全接入、语音、视频、无线等多种业务&#xff0c;支持各种接入方式和协议&#xff0c;并且可以方便地进行扩展和升级。 实验拓扑图&…

BGP基础

BGP是什么 BGP Border Gateway Protocol&#xff08;当前使用的版本是 BGP-4&#xff09; 动态路由协议可以按照工作范围分为IGP以及EGP。IGP工作在同一个AS内&#xff0c;主要用来发现和计算路由&#xff0c;为AS内提供路由信息的交换&#xff1b;而EGP工作在AS与AS之间&…

一文汇总对比英伟达、AMD、英特尔显卡GPU

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f4d1;上期文章&#xff1a;『【仪酷LabVIEW AI工具包案例】使用LabVIEW AI工具包YOLOv5结合Dobot机械臂实现智能垃圾分类』 &#x1f37b;本文由virobotics(仪酷…

AVL树的完全指南:平衡与性能

文章目录 AVL树简介AVL的操作建立一个AVL树插入操作删除操作 书写代码1.构造函数和析构函数2.获取最大值和最小值3.树的高度和节点个数3.前序中序和后序遍历4.判断树是否为空树5.四个旋转操作6.获取平衡因子7.插入操作8.删除操作9.搜索节点.h文件中的定义 总结 AVL树简介 AVL树…

ICode国际青少年编程竞赛- Python-4级训练场-嵌套for循环入门

ICode国际青少年编程竞赛- Python-4级训练场-嵌套for循环入门 1、 for i in range(3):Dev.step(3)for j in range(3):Dev.turnLeft()Dev.step(-2)Dev.turnLeft()2、 for i in range(3):Dev.turnLeft()Dev.step(4)Dev.turnRight()Dev.step(2)for i in range(4):Dev.step(2)D…

nginx目录枚举修复手册

nginx目录枚举修复手册 漏洞背景 修复方式: ssh zujian2 sudo vi /data/apps/nginx/conf/conf.d/default.conf server {

网页如何集成各社区征文活动

Helllo , 我是小恒 由于我需要腾讯云社区&#xff0c;稀土掘金以及CSDN的征文活动RSS&#xff0c;找了一下没发现&#xff0c;所以使用GET 请求接口对网页定时进行拉取清洗&#xff0c;甚至无意间做了一个简单的json格式API 最终网址:hub.liheng.work API:http://hub.liheng.wo…

升级! 测试萌新Python学习之连通数据库Pymsql增删改及封装(四)

pymysql 数据库概述python对数据库的增删改查pymysql核心操作事务事务操作pymysql工具类封装每日复习ChatGPT的回答 数据库概述 分类 关系型数据库: 安全 如, mysql oracle SQLite…database tables 行列 非关系型数据库: 高效 如, redis mongoDB…数据存储结构多样 键值对…

Python Socket

一、服务端 from socket import *def print_hi(name):print(fHi, {name})# 允许所有ip连接IP 0.0.0.0# 端口PORT 8003# 定义一次从socket缓冲区读入512个字节数据BUFFER_LEN 512# 实例化socket对象 listenSocket 用来监听的socketlistenSocket socket(AF_INET, SOCK_STREA…

怎么通过微信小程序实现远程控制8路控制器/断路器

怎么通过微信小程序实现远程控制8路控制器/断路器呢&#xff1f; 本文描述了使用微信小程序调用HTTP接口&#xff0c;实现控制8路控制器/断路器&#xff0c;支持8路输出&#xff0c;均可独立控制&#xff0c;可接入各种电器。 可选用产品&#xff1a;可根据实际场景需求&#…

DS:顺序表、单链表的相关OJ题训练(2)

欢迎各位来到 Harper.Lee 的学习世界&#xff01; 博主主页传送门&#xff1a;Harper.Lee的博客主页 想要一起进步的uu欢迎来后台找我哦&#xff01; 一、力扣--141. 环形链表 题目描述&#xff1a;给你一个链表的头节点 head &#xff0c;判断链表中是否有环。如果链表中有某个…

提升网络性能,解决网络故障,了解AnaTraf网络流量分析仪

在当今数字化时代&#xff0c;网络性能监测与诊断(Network Performance Monitoring and Diagnosis,NPMD)成为了企业和个人关注的焦点。随着网络流量不断增长&#xff0c;确保网络的稳定性和高效性变得更加重要。在这个领域&#xff0c;AnaTraf网络流量分析仪是您不可或缺的得力…

从“金事通”带给我意想不到的来说--“数据是架构的中心”

背景 上周一个保险的销售人员来找我完成一定的售后流程。其中有一项是请我下载一个叫 金事通的 APP。说实在的我根本没听过。她说这是政治任务。我想不是有你们保险公司的APP了嘛。为什么还要我安装。没办法先安装吧。 经历了注册、人脸识别的步骤后。可以登录了。注册短信发…

使用Docker+Jar方式部署微服务工程(前后端分离)看着一篇就够了

本篇教程的使用到的技术有springboot、springcloud、Nacos、Docker、Nginx部署前后端分离访问的微服务。 部署一下Nacos 首先我们需要在服务器中&#xff08;或者本地部署启动一下Nacos&#xff09;&#xff0c;这里我采用服务器的方式进行部署&#xff0c;这里有一点不一样的…

前端开发者必备:Nginx入门实战宝典,从部署到优化一网打尽

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 引言 &#x1f44b;一、Nginx简介 &#x1f4da;二、常见的Web服务器架构 &#x1f300;&#x1f4cc; 架构概述&#x1f4cc; Nginx的深入探讨 三、正向代理与反向代理 &#x1f52e;&#x1f4cc; 正向代理工作原理&#…

RabbitMQ(四种使用模式)

文章目录 1.Fanout&#xff08;广播模式&#xff09;1.基本介绍2.需求分析3.具体实现1.编写配置类 RabbitMQConfig.java2.编写生产者&#xff0c;发送消息到交换机 MQSender.java3.编写消费者&#xff0c;接受消息 MQReceiver.java4.控制层调用方法&#xff0c;发送信息到交换机…

工程师工具箱系列(3)Arthas

文章目录 工程师工具箱系列&#xff08;3&#xff09;Arthas安装与准备Arthas插件使用场景查看某个变量值ognl方式调用Bean方法tt(TimeTunel)方式调用Bean的方法ognl调用带参数方法 资源总览 工程师工具箱系列&#xff08;3&#xff09;Arthas Java诊断利器 安装与准备 window…