Python - 深夜数据结构与算法之 位运算

目录

一.引言

二.位运算简介

1.二进制与十进制

2.左/右移

3.位运算

4.异或 XOR

5.指定位置的位运算

6.实战要点

三.经典算法实战

1.Number-1-of-bits [191]

2.Power-Of-Two [231]

3.Reverse-2-Bits [190]

4.N-Queens [51]

四.总结


一.引言

通常情况下我们计数采取十进制,这是因为日常生活中我们习惯了 0-9 的数字习惯,而对于计算机而言,其通过 0-1 的二进制方式表示和存储数字。本节开始我们学习二进制以及其对应的位运算。

二.位运算简介

1.二进制与十进制

机器中数字的表示和存储格式就是二进制,给定数字 0101 其等于从后向前:

1 * 2^{0} + 0 * 2^{1} + 1 * 2^{2} + 0 * 2^{3} = 1 + 0 + 4 + 0 = 5

即对应位置的索引作为 2 的指数,对应位置的值作为指数幂的系数,累加即为 10 进制的数字。

相反的,如果想把一个 10 进制的数字转换为 2 进制,则我们依次除 2 取余,把得到的数字反转即可得到其二进制。这里不好理解的话可以对照着上面 10 进制转 2 进制的公式再思考思考。上面的图片来自: wikihow,是一个很好玩的百科网站,大家可以去搜索你想了解的内容。

2.左/右移

左移右移就是把当前二进制数字向左或向右移动一个位置,空出来的位置补 0 ,被顶出去的位置就不要了。我们老式的计算机一般是采用 32 位表示,而新的计算机则都采用了 64 位表示。

3.位运算

- 按位或  有一个 1,则或出来就是 1

- 按位与  有一个 0 ,则与出来就是 0 

- 按位取反 0 变成 1,1 变成 0 

- 按位异或   相同为 0,不同为 1

以上位运算都是在两个二进制数字之间展开。

4.异或 XOR

这里 1s 代表全为 1,即把 0 取反 ~0。 后面两条定律使用的比较少,前面四条性质比较常用。

5.指定位置的位运算

上面给出了一些位运算常见的位置操作,用于我们处理对应位置的位数。 

6.实战要点

判断奇偶以及 /2 的常规操作,我们都可以改写为位运算的方式提高效率,除此之外通过 & 方法可以得到清除、得到最低位 1 的操作。

三.经典算法实战

1.Number-1-of-bits [191]

位1的个数: https://leetcode.cn/problems/number-of-1-bits/description/

◆ 题目分析

& 操作是, 1 & x = x,所以我们可以遍历 32 位数的每一位 & 1 的值,如果为 1 则说明该位为 1,则 cnt += 1,或者使用上面实战要点中 X = X & (X-1) 清零最低位 1 的操作,能清几次代表有几个 1。

◆ 1 & x = x

class Solution(object):def hammingWeight(self, n):""":type n: int:rtype: int"""cnt = 0for i in range(32):if n & (1 << i):cnt += 1return cnt

 ◆ x & (x-1) 

class Solution(object):def hammingWeight(self, n):""":type n: int:rtype: int"""cnt = 0while n:n = n & (n-1)cnt += 1return cnt

 n & (n-1) 的示意图可以参考上面的过程。

2.Power-Of-Two [231]

2的幂: https://leetcode.cn/problems/power-of-two/description/

◆ 题目分析

套用上面的 1 bits 方法,由于2的幂次一定只有 1 位有 1,所以判断 cnt 是否为 1 即可。也可以一直 % 2 并 / 2,看能不能一直除下去。

◆ x & (x-1)

class Solution(object):def isPowerOfTwo(self, n):""":type n: int:rtype: bool"""if n == 0:return Falsereturn n & (n-1) == 0

◆ x % 2 - x / 2

class Solution(object):def isPowerOfTwo(self, n):""":type n: int:rtype: bool"""if n == 1:return Trueif n <= 0 or n % 2:return Falsereturn self.isPowerOfTwo(n / 2)

3.Reverse-2-Bits [190]

颠倒 2 进制: https://leetcode.cn/problems/reverse-bits/description/ 

◆ 题目分析

把 n 的 32 位,每一位拿出来再往后追加,类似于一位一位 reverse。

◆ x << 1

class Solution:# @param n, an integer# @return an integerdef reverseBits(self, n):res = 0for i in range(32):# 有 1 就 1,没 1 就 0res = (res << 1) | (n & 1)n >>= 1return res

res << 1: 把最后一位空出来

n & 1: 0 是 0、1 是 1

|: 前面 res 部分不动,后面 0 是 0、1 是 1 

通过这三部分实现反转与追加。 

4.N-Queens [51]

N 皇后: https://leetcode.cn/problems/n-queens/description/ 

◆ 题目分析

老生常谈的问题了, 传统的办法我们是构造了 pie、na、row 三个 set 进行去重,学习了位运算后,我们也可以将棋盘按 45 度划分 2n-1 个对角线,这样 pie、na 就只需要位运算判重而不需要 set 了,提高了空间利用率和时间效率。

◆ DFS + Set

class Solution(object):def solveNQueens(self, n):""":type n: int:rtype: List[List[str]]"""results = []# 行 左 右 是否可以放置cols = set()pie = set()na = set()def dfs(n, row, cur):if row >= n:results.append(cur)for col in range(n):if col in cols or (row + col) in pie or (row - col) in na:continue# 判断有效cols.add(col)pie.add(row + col)na.add(row - col)dfs(n, row + 1, cur + [col])# 恢复状态cols.remove(col)pie.remove(row + col)na.remove(row - col)dfs(n, 0, [])return self.genResult(n, results)def genResult(self, n, results):return [[ '.' * i + 'Q' + (n - i - 1) * '.' for i in result] for result in results]def genResultV2(self, n, results):re = []for result in results:re.append([ '.' * i + 'Q' + (n - i - 1) * '.' for i in result])return re

◆ DFS + Simple Set

class Solution(object):def solveNQueens(self, n):""":type n: int:rtype: List[List[str]]"""results = []def dfs(queue, diff, total):row = len(queue)if row == n:results.append(queue)return Nonefor col in range(n):if col not in queue and row + col not in total and row - col not in diff:dfs(queue + [col], diff + [row - col], total + [row + col])dfs([], [], [])return [[ '.' * i + 'Q' + (n - i - 1) * '.' for i in result] for result in results]

◆ DFS + Bit

class Solution(object):def power_of_two(self, num):power = 0while num % 2 == 0:power += 1num = num / 2return powerdef solveNQueens(self, n):""":type n: int:rtype: List[List[str]]"""if n < 1:return []results = []def DFS(n, row, cols, pie, na, cur):if row >= n:results.append(cur)return# 得到当前所有空位bits = (~(cols | pie | na) & ((1 << n) - 1))while bits:p = bits & -bits  # 取最低位的 1bits = bits & (bits - 1)  # P 位置放置皇后DFS(n, row + 1, cols | p, (pie | p) << 1, (na | p) >> 1, cur + [p])DFS(n, 0, 0, 0, 0, [])return [['.' * self.power_of_two(i) + 'Q' + (n - self.power_of_two(i) - 1) * '.' for i in result] for result in results]

这里 bits 以及一些递进的操作直接看容易懵,大家可以在 n=4 的情况下,打印每一次运算的 2 进制,感受下如何通过位运算求解,这里可以通过 bin() 方法获取二进制表示。

四.总结

位运算的解法和题目相对来说比较抽象,不理解的时候还是多转换为 2 进制数字,查看其演进的过程,更好的熟悉其推导过程。

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

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

相关文章

Flink-SQL——时态表(Temporal Table)

时态表(Temporal Table) 文章目录 时态表(Temporal Table)数据库时态表的实现逻辑时态表的实现原理时态表的查询实现时态表的意义 Flink中的时态表设计初衷产品价格的例子——时态表汇率的例子——普通表 声明版本表声明版本视图声明普通表 一个完整的例子测试数据代码实现测试…

使用Github + PicGo搭建个人图床,并使用CDN加速

文章目录 前言创建仓库配置PicGo如何使用 前言 在写博客的时候&#xff0c;常常需要为博客配图&#xff0c;于是一个好用稳定的图床的重要性不言而喻。本文主要介绍如何使用GitHub PicGo的方式快速搭建一个个人使用的图床。该方式方便快捷&#xff0c;还免费hh&#xff0c;唯…

python 集合的详细用法

当前版本&#xff1a; Python 3.8.4 简介 Python中的集合是一种无序、可哈希的且不重复的数据类型&#xff0c;用于存储唯一的元素。集合的实现基于哈希表&#xff0c;因此在插入、查找和删除元素时具有高效性能。集合的每个元素都必须是不可变的&#xff0c;可以是数字、字符…

瑞_Java开发手册_(二)异常日志

文章目录 异常日志的意义(一) 错误码(二) 异常处理(三) 日志规约附&#xff1a;错误码列表 &#x1f64a;前言&#xff1a;本文章为瑞_系列专栏之《Java开发手册》的异常日志篇&#xff0c;本篇章主要介绍异常日志的错误码、异常处理、日志规约。由于博主是从阿里的《Java开发手…

基于Redis+Lua的分布式限流

本文已收录至我的个人网站&#xff1a;程序员波特&#xff0c;主要记录Java相关技术系列教程&#xff0c;共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源&#xff0c;让想要学习的你&#xff0c;不再迷茫。 前面我们了解了如何利用Nginx做网关层限流&#xf…

Microsoft Remote Desktop for Mac 中文正式版下载 微软远程连接软件

Microsoft Remote Desktop 是一款专为 Mac 用户设计的远程桌面工具&#xff0c;它可以帮助用户通过网络连接到其他计算机&#xff0c;实现远程控制和操作。 软件下载&#xff1a;Microsoft Remote Desktop for Mac 中文正式版下载 该工具支持多种远程连接协议&#xff0c;包括 …

【数学建模美赛M奖速成系列】数据可视化方法(一)

数据可视化方法 写在前面山脊图优点缺点实现matlabpython 气泡矩阵图实现matlabpython 后续 写在前面 最近开始更新一个新的系列科研绘图&#xff0c;在同一个竞赛下&#xff0c;大家都近乎相同的解题思路下。之所以能出现一等二等三等奖的区别很大部分都在于结果的可视化&…

Docker 容器之间的互相通信

Docker容器之间的互相通信 步骤一&#xff1a;创建自定义网络 首先&#xff0c;我们需要创建一个自定义网络&#xff0c;以便容器可以连接到这个网络上&#xff0c;从而实现互相通信。在命令行中执行以下命令&#xff1a; # 创建 docker network create ddz # 查看 docker n…

利用Socket动手实现简单HTTP协议

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

python 元组的详细用法

当前版本&#xff1a; Python 3.8.4 文章目录如下 1. 介绍元组 2. 定义元组 3. 访问元组 4. 查询元组 1. 介绍元组 元组&#xff08;Tuple&#xff09;是一个有序的、不可变的数据序列。它可以包含各种类型的数据&#xff0c;例如数字、字符串、列表等。元组使用圆括号()来…

Elasticsearch:聊天机器人教程(二)

这是继上一篇文章 “Elasticsearch&#xff1a;聊天机器人教程&#xff08;一&#xff09;”的续篇。本教程的这一部分讨论聊天机器人实现中最有趣的方面&#xff0c;以帮助你理解它并对其进行自定义。 数据摄入 在此应用程序中&#xff0c;所有示例文档的摄取都是通过 flask …

2024年信息安全不完全预测

不需要专家预言就能知道&#xff0c;计算机安全将在2024年出现在新闻中&#xff0c;而且可能不是什么好事。但2024年网络犯罪分子将如何试图突破防御并窃取有价值的数据&#xff0c;值得我们看一看安全专家们的看法和预测。 不需要专家预言就能知道&#xff0c;计算机安全将在…

【深度学习I-基础知识】

深度学习I-基础知识 1 基础知识1.1 模型的基本概念1.2 机器学习1.2.1 概率建模1.2.2 核方法1.2.3 决策树、随机森林和梯度提升机 1.3 深度学习1.3.1 张量1.3.2 数据批量1.3.3 张量运算1.3.4 训练过程 1 基础知识 1.1 模型的基本概念 模型是现实世界中一类具有泛化共性的真实系…

canvas截取视频图像(图文示例)

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

2023一带一路暨金砖国家技能发展与技术创新大赛“网络安全”赛项省选拔赛样题卷②

2023金砖国家职业技能竞赛"网络安全" 赛项省赛选拔赛样题 2023金砖国家职业技能竞赛 省赛选拔赛样题第一阶段&#xff1a;职业素养与理论技能项目1. 职业素养项目1. 职业素养项目2. 网络安全项目3. 安全运营 第二阶段&#xff1a;安全运营项目1. 操作系统安全配置与加…

Docker部署的gitlab升级指南(15.11.X容器里升级PostgreSQL到13.8)

一、确定当前版本 #进入当前版本容器产看gitlab版本 docker exec -it gitlab cat /opt/gitlab/embedded/service/gitlab-rails/VERSION#显示版本如下 14.4.0二、备份数据&#xff0c;防止升级发生意外 #执行备份命令 docker exec -ti gitlab gitlab-rake gitlab:backup:creat…

go的安装及配置

go的官方下载地址&#xff1a;All releases - The Go Programming Language​​​​​​ 1、找到对应的版本包下载&#xff0c;例如 wget https://golang.google.cn/dl/go1.21.6.linux-amd64.tar.gz 2、下载完成后配置解压Go源码包 tar -zxf go1.21.6.linux-amd64.tar.gz 3…

【IC设计】ICer‘s 乾坤大挪移——FSM状态机

目录 理论解读状态机定义状态转移图Mealy和Moore型状态机推荐写“新两段式状态机” 设计实战可乐机两种state的FSM&#xff08;异步复位&#xff09;4种状态的one-hot状态机4种状态的同步复位状态机蓄水池问题 参考链接 理论解读 状态机定义 状态机简写为 FSM&#xff08;Fin…

Python3 索引下标及切片完全指南

介绍 Python 字符串数据类型是由一个或多个字符组成的序列&#xff0c;可以包含字母、数字、空格字符或符号。由于字符串是一个序列&#xff0c;我们可以通过索引和切片的方式访问它&#xff0c;就像访问其他基于序列的数据类型一样。 本教程将指导您通过索引访问字符串&…

网络攻击与检测防御:维护数字安全的关键挑战

随着数字化时代的深入&#xff0c;网络攻击已成为企业和个人面临的严峻挑战之一。本文将深入探讨不同类型的网络攻击&#xff0c;以及有效的检测和防御策略&#xff0c;以确保网络系统的安全性和稳定性。 1. 常见网络攻击类型&#xff1a; DDoS 攻击&#xff1a;分布式拒绝服…