【LeetCode刷题笔记(6-2)】【Python】【三数之和】【双指针】【中等】
文章目录
- 引言
- 三数之和
- 题目描述
- 示例
- 示例1
- 示例2
- 示例3
- 提示
- 解决方案3:【双指针】
- 结束语
三数之和
引言
编写通过所有测试案例的代码并不简单,通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例,但如果不了解代码背后的思考过程,那么这些代码可能并不容易被理解和接受。我编写刷题笔记的初衷,是希望能够与读者们分享一个完整的代码是如何在逐步的理性思考下形成的。我非常欢迎读者的批评和指正,因为我知道我的观点可能并不完全正确,您的反馈将帮助我不断进步。如果我的笔记能给您带来哪怕是一点点的启示,我也会感到非常荣幸。同时,我也希望我的分享能够激发您的灵感和思考,让我们一起在编程的道路上不断前行~
三数之和
题目描述
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。
请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例
示例1
- 输入:nums = [-1,0,1,2,-1,-4]
- 输出:[[-1,-1,2],[-1,0,1]]
示例2
- 输入:nums = [0,1,1]
- 输出:[]
- 解释:唯一可能的三元组和不为 0 。
示例3
- 输入:nums = [0,0,0]
- 输出:[[0,0,0]]
- 解释:唯一可能的三元组和为 0 。
提示
- 3 <= nums.length <= 3000
- -105 <= nums[i] <= 105
解决方案3:【双指针】
在博客【LeetCode刷题笔记(6-1)】【Python】【三数之和】【哈希表】【中等】中,我们详尽地探讨了如何利用【哈希表】精妙设计算法,从而顺利通关【三数之和】这一挑战。
在此过程中,我们深度挖掘了问题细节,确保算法能够通过所有的测试案例(基于哈希表设计的算法在【三数之和】上很容易超时) —> 这不仅是一次技术上的磨练,更是对细心与耐心的极致考验。
问题1:为什么【三数之和】问题可以用【双指针】来解决?
在博客【LeetCode刷题笔记(6-1)】【Python】【三数之和】【哈希表】【中等】中,我们从两数之和的解决方案中汲取灵感,通过举一反三,巧妙地运用哈希表来解决【三数之和】问题。而对于【双指针】的使用,背后又隐藏着怎样的深刻逻辑呢?—> 先回到三数之和的本质:查找目标值。
在【哈希表】解决方案中,我们通过两层遍历的方式,首先固定两个值,然后利用哈希表快速查找剩下的一个值。那么,除了哈希表外,是否还有其他算法可以达到类似的效果呢?答案是肯定的,那就是双指针方法。
通过固定一个值,然后使用双指针在数组中查找剩余的两个值,同样可以达到解决问题的目的。这种方法的优势在于,它避免了哈希表的开销,同时保持了查找的效率。
我们可以把双指针分为左指针left
和右指针right
。在循环遍历数组nums
的每个元素nums[i]
时,设计算法找到正确的nums[left]
和nums[right]
, 共同组成满足题意的三元组[nums[i], nums[left], nums[right]]
。
代码的初始版本如下:
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: # 如果输入的数组为空或长度小于3,直接返回空列表 if not nums or len(nums) < 3: return [] # 对输入的数组进行排序nums.sort() # 获取列表的长度 n = len(nums) # 初始化结果列表 result_list = [] # 遍历数组中的每个元素 --> 固定元素nums[i]for i in range(n): # 初始化左指针和右指针,分别指向剩余两个元素的位置 left = 0 right = n - 1 # 当左指针小于右指针时,进行循环 while left < right: # 如果三个元素的和等于0,则将这三个元素添加到结果列表中,并同时移动左指针和右指针if nums[i] + nums[left] + nums[right] == 0: result_list.append([nums[i], nums[left], nums[right]]) left += 1 # 左指针右移right -= 1 # 右指针左移 # 如果三个元素的和大于0,则右指针向左移动,以减少和的值 elif nums[i] + nums[left] + nums[right] > 0: right -= 1 else: # 如果三个元素的和小于0,则左指针向右移动,以增加和的值 left += 1 return result_list # 返回结果列表
初步运行结果
可以看到,虽然结果列表中,包含了正确的三元组,但更多的是重复的三元组(如上图的蓝色框部分),甚至还出现重复利用数组元素的三元组(上图红色框,重复利用元素2)。
尽管初始的代码版本问题很大,但还是有一些小细节值得拎出来说明一下:
细节1:为什么要对数组nums进行排序?
如果您已看完这篇博客,您会知道其中一个原因是为了方便去重。但目前的【初始代码】压根与去重无关。其实,现阶段对数组nums
进行排序的原因是为了方便确定左指针left
和右指针right
的移动方向。
- 如果数组
nums
是乱序的,如果nums[i] + nums[left] + nums[right] > 0
,下一步是移动左指针还是右指针?显然是不确定的。 - 如果数组
nums
是有序的,比如说从小到大排列。那么left
右移 ==> 三元组之和将增加;同理,right
左移 ==> 三元组之和将减少;那么nums[i] + nums[left] + nums[right] > 0
,下一步自然是right
左移,使三元组之和进一步接近0。
从细节1的分析中我们可以看出,对数组nums
进行排序对于应用双指针算法解决三数之和问题至关重要。甚至可以说,方便去重只是这个过程中的一个额外的好处,就像“买一送一”一样。
细节2:while left < right:
这个语句能否取等,即while left <= right:
?
不能。我们可以从左右指针的定义中找到答案 ==> 分别指向剩余两个元素的位置。如果left == right
成立 ⇒ 三元组会包含同一元素!
细节3:当三元组元素满足nums[i] + nums[left] + nums[right] == 0
时,为什么下一步要同时进行left
右移和right
左移?
- 如果我们只进行
left
右移,相当于nums[i]
和nums[left]
是固定的。想要nums[i] + nums[left] + nums[right] == 0
继续成立,nums[right]即使元素位置变了,但元素值不可能变 ==> 只移动一个指针没有意义,都不移动更没有意义 —> 同时进行left
右移和right
左移。
想清楚三个细节后,紧接着就要思考为什么这个代码会生成这么多重复的三元组,甚至还出现重复利用数组元素的三元组?
问题1:左指针left
不应该初始化为0
如果我们把左指针left
初始化为0 ⇒ 在【双指针】查找剩余两个元素时,左指针left
的右移和右指针right
的左移都可能碰上事先固定的元素nums[i]
⇒ 出现重复利用数组元素的三元组。既然0不行,那么初始化为[0, i]的任何数都会出现这样的问题。
那将左指针left
初始化为i+1?
是的,这样既可以保证左指针left
的右移和右指针right
的左移不可能会碰到事先固定的元素nums[i]
,也不会出现遗漏某个三元组的情况。
代码如下(见修改1):
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: # 如果输入的数组为空或长度小于3,直接返回空列表 if not nums or len(nums) < 3: return [] # 对输入的数组进行排序nums.sort() # 获取列表的长度 n = len(nums) # 初始化结果列表 result_list = [] # 遍历数组中的每个元素 --> 固定元素nums[i]for i in range(n): # 初始化左指针和右指针, 分别指向剩余两个元素的位置 left = i + 1 # 修改1:初始化为i+1right = n - 1 # 当左指针小于右指针时,进行循环 while left < right: # 如果三个元素的和等于0,则将这三个元素添加到结果列表中,并同时移动左指针和右指针if nums[i] + nums[left] + nums[right] == 0: result_list.append([nums[i], nums[left], nums[right]]) left += 1 # 左指针右移right -= 1 # 右指针左移 # 如果三个元素的和大于0,则右指针向左移动,以减少和的值 elif nums[i] + nums[left] + nums[right] > 0: right -= 1 else: # 如果三个元素的和小于0,则左指针向右移动,以增加和的值 left += 1 return result_list # 返回结果列表
运行结果
可以看到,相比于上一版代码,这一版结果虽然仍然存在重复的三元组,但已经没有出现重复利用数组元素的三元组!<— 这是由于这版代码中, i < left < right
的关系是恒成立的,保证了不可能重复利用数组元素。
问题2:为什么仍然存在重复的三元组[-1, 0, 1]呢?
数组[-1,0,1,2,-1,-4]
排序后的结果为[-4, -1, -1, 0, 1, 2]
⇒ 当遍历数组元素,依次固定元素值时,元素-1
会连续两次作为固定的值 ⇒ 结果列表中多了一个三元组!!!
由于数组是有序的,我们可以很简单的对这种情况进行去重操作,代码如下(见修改2):
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: # 如果输入的数组为空或长度小于3,直接返回空列表 if not nums or len(nums) < 3: return [] # 对输入的数组进行排序nums.sort() print(nums)# 获取列表的长度 n = len(nums) # 初始化结果列表 result_list = [] # 遍历数组中的每个元素 --> 固定元素nums[i]for i in range(n):# 修改2:去除连续相同的元素值if i > 0 and nums[i] == nums[i-1]:continue# 初始化左指针和右指针, 分别指向剩余两个元素的位置 left = i + 1 # 修改1:初始化为i+1right = n - 1 # 当左指针小于右指针时,进行循环 while left < right: # 如果三个元素的和等于0,则将这三个元素添加到结果列表中,并同时移动左指针和右指针if nums[i] + nums[left] + nums[right] == 0: result_list.append([nums[i], nums[left], nums[right]]) left += 1 # 左指针右移right -= 1 # 右指针左移 # 如果三个元素的和大于0,则右指针向左移动,以减少和的值 elif nums[i] + nums[left] + nums[right] > 0: right -= 1 else: # 如果三个元素的和小于0,则左指针向右移动,以增加和的值 left += 1 return result_list # 返回结果列表
运行结果
可以看到,目前代码已经通过132个测试用例,但仍然会出现重复的三元组。
问题3:为什么仍然存在重复的三元组[-2, 0, 2]呢?,我们可以从排序后的数组[-2, 0, 0, 2, 2]
看出,0和2分别重复了两次 ⇒ 当我们固定元素-2时,并快速找到[-2, 0, 2]
这个正确的三元组,此时左指针left
右移,右指针right
左移。巧的是,左指针left
依然指向元素0,右指针依然指向元素2 ⇒ 出现重复的三元组[-2, 0, 2]。
因此我们在找到正确三元组的同时,应该把与左指针left
指向的元素相同的过滤掉,也把与右指针right
指向的元素相同的过滤掉。代码如下(见修改3):
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: # 如果输入的数组为空或长度小于3,直接返回空列表 if not nums or len(nums) < 3: return [] # 对输入的数组进行排序nums.sort() print(nums)# 获取列表的长度 n = len(nums) # 初始化结果列表 result_list = [] # 遍历数组中的每个元素 --> 固定元素nums[i]for i in range(n):# 修改2:去除连续相同的元素值if i > 0 and nums[i] == nums[i-1]:continue# 初始化左指针和右指针, 分别指向剩余两个元素的位置 left = i + 1 # 修改1:初始化为i+1right = n - 1 # 当左指针小于右指针时,进行循环 while left < right: # 如果三个元素的和等于0,则将这三个元素添加到结果列表中,并同时移动左指针和右指针if nums[i] + nums[left] + nums[right] == 0: result_list.append([nums[i], nums[left], nums[right]]) # 修改3while left < right and nums[left] == nums[left+1]: left += 1 # 如果左边的元素相等,则移动左指针 while left < right and nums[right] == nums[right-1]: right -= 1 # 如果右边的元素相等,则移动右指针 left += 1 # 左指针右移right -= 1 # 右指针左移 # 如果三个元素的和大于0,则右指针向左移动,以减少和的值 elif nums[i] + nums[left] + nums[right] > 0: right -= 1 else: # 如果三个元素的和小于0,则左指针向右移动,以增加和的值 left += 1 return result_list # 返回结果列表
运行结果
可以看到,目前代码已经能够通过所有测试案例,但代码运行时间显然还是比较长的。
问题4:还有没有进一步优化的可能性?
有的。
首先,数组nums
是排好序的,而我们的目标是找三个元素,让它们的和为0 ⇒ 如果当前固定的值为nums[i] > 0 ⇒ 根据i < left < right
, 即nums[i] < nums[i] < nums[i]
恒成立,不可能找到和为0的三元组,此时应该直接返回结果。
问题5:nums[i] = 0 的情况是否要保留,即返回条件是否可改为nums[i] >= 0
?
不可以,因为可能存在[0, 0, 0]
这个正确的三元组!代码如下(见修改4):
完整代码:
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: # 如果输入的数组为空或长度小于3,直接返回空列表 if not nums or len(nums) < 3: return [] # 对输入的数组进行排序nums.sort() # print(nums)# 获取列表的长度 n = len(nums) # 初始化结果列表 result_list = [] # 遍历数组中的每个元素 --> 固定元素nums[i]for i in range(n):# 修改2:去除连续相同的元素值if i > 0 and nums[i] == nums[i-1]:continue# 修改4 if nums[i] > 0:return result_list# 初始化左指针和右指针, 分别指向剩余两个元素的位置 left = i + 1 # 修改1:初始化为i+1right = n - 1 # 当左指针小于右指针时,进行循环 while left < right: # 如果三个元素的和等于0,则将这三个元素添加到结果列表中,并同时移动左指针和右指针if nums[i] + nums[left] + nums[right] == 0: result_list.append([nums[i], nums[left], nums[right]]) # 修改3while left < right and nums[left] == nums[left+1]: left += 1 # 如果左边的元素相等,则移动左指针 while left < right and nums[right] == nums[right-1]: right -= 1 # 如果右边的元素相等,则移动右指针 left += 1 # 左指针右移right -= 1 # 右指针左移 # 如果三个元素的和大于0,则右指针向左移动,以减少和的值 elif nums[i] + nums[left] + nums[right] > 0: right -= 1 else: # 如果三个元素的和小于0,则左指针向右移动,以增加和的值 left += 1 return result_list # 返回结果列表
运行结果:
复杂度分析
- 时间复杂度:O(N2),其中 N 是数组
nums
元素的数量。 - 空间复杂度:O(N)
- 存放数组排序后的新数组 ===> O(N)
结束语
- 亲爱的读者,感谢您花时间阅读我们的博客。我们非常重视您的反馈和意见,因此在这里鼓励您对我们的博客进行评论。
- 您的建议和看法对我们来说非常重要,这有助于我们更好地了解您的需求,并提供更高质量的内容和服务。
- 无论您是喜欢我们的博客还是对其有任何疑问或建议,我们都非常期待您的留言。让我们一起互动,共同进步!谢谢您的支持和参与!
- 我会坚持不懈地创作,并持续优化博文质量,为您提供更好的阅读体验。
- 谢谢您的阅读!
相关文章:

【LeetCode刷题笔记(6-2)】【Python】【三数之和】【双指针】【中等】
文章目录 引言三数之和题目描述示例示例1示例2示例3 提示 解决方案3:【双指针】结束语 三数之和 引言 编写通过所有测试案例的代码并不简单,通常需要深思熟虑和理性分析。虽然这些代码能够通过所有的测试案例,但如果不了解代码背后的思考过程…...

02_Web开发基础之JavaScript
Web开发基础之JavaScript 学习目标和内容 1、能够描述Javascript的作用 2、能够使用分支结构if语句逻辑判断 3、能够使用其中一种循环语句 4、能够定义javaScript中的函数 5、能够定义javaScript中的对象 6、能够描述DOM的作用 7、能够通过DOM操作HTML标签元素及其属性 8、能够…...
如何控制Elasticsearch搜索的相关性?
控制相关性 纯粹处理结构化数据(例如日期、数字和 字符串枚举)很简单:他们只需要检查一个文档(或 行,在关系数据库中)与查询匹配。 虽然布尔值是/否匹配是全文搜索的重要组成部分,但它们 光靠自己是不够的。相反,我们还需要知道每个的相关性 document 是查询。全文搜索…...

基于urllib库的网页数据爬取
实验名称: 基于urllib库的网页数据爬取 实验目的及要求: 【实验目的】 通过本实验了解和掌握urllib库。 【实验要求】 1. 使用urllib库爬取百度搜索页面。 2. 使用urllib库获取百度搜索的关键字搜索结果(关键字任选)。 实验原理及…...

Python如何匹配库的版本
目录 1. 匹配库的版本 2. Python中pip,库,编译环境的问题回答总结 2.1 虚拟环境 2.2 pip,安装库,版本 1. 匹配库的版本 (别的库的版本冲突同理) 在搭建pyansys环境的时候,安装grpcio-tools…...

日志审计在网络安全中的重要性
日志审计是一种通过分析、识别和验证各种日志信息,以帮助企业了解其网络和系统的安全状态和活动的过程。这些日志信息可能来自各种来源,包括服务器、网络设备、应用程序、操作系统等。 日志审计的主要功能包括: 1.识别潜在的安全威胁&#…...
浅谈基于不信任的防御性编程
背景 在实际开发过程中,我们经常遇到这样的场景: 后端报错了,手忙脚乱一顿排查,发现是前端传的参数为空,或者格式不对;后端又报错了,传参没问题,根据日志流发现,是某“给…...

线性代数(一)
1.标量:标量由只有⼀个元素的张量表⽰。 x np.array(3.0) y np.array(2.0) x y, x * y, x / y, x ** y (array(5.), array(6.), array(1.5), array(9.))2.向量:向量可以被视为标量值组成的列表,列向量是向量的默认⽅向。 x np.arange(4…...
k8s-learning-why we need pod
应用场景 应用从虚拟机迁移到容器中 为什么虚拟机中的应用不能无缝迁移到容器中 虚拟机中应用:一组进程,被管理在systemd或者supervisord中 容器的本质:一个容器一个进程 所以将运行在虚拟机中的应用无缝迁移到容器中,与容器…...

【CASS精品教程】cass11提示“请不要在虚拟机中运行此程序”的解决办法
文章目录 一、问题提示二、解决办法一、问题提示 按照正常安装教程安装好南方测绘cass 11之后,打开的时候可能会有以下提示:请不要在虚拟机中运行此程序,如下图所示: 遇到问题,咱们就想办法解决问题,下面将自己尝试的方法及最终解决情况跟大家说一下,供参考。 二、解决…...

【算法Hot100系列】正则表达式匹配
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
html 基础学习笔记
Date:20231212 html标签 基础学习笔记 一、web和internet 1.1、Internet简介 Internet 是一个全球性的计算机互联网络,中文名称有"因特网"、“国际互联网”、“网际网”、"交互网络"等Internet提供的主要服务 Telnet、Email、www、BBS、FTP等…...
7-4 天梯赛的善良
天梯赛是个善良的比赛。善良的命题组希望将题目难度控制在一个范围内,使得每个参赛的学生都有能做出来的题目,并且最厉害的学生也要非常努力才有可能得到高分。 于是命题组首先将编程能力划分成了 106 个等级(太疯狂了,这是假的&…...

案例精选|聚铭综合日志分析系统助力长房集团“智慧房产”信息化建设
长沙房产(集团)有限公司(简称“长房集团”)始创于2004年3月,是一家由长沙市人民政府授权组建的国有独资企业。截至2021年底,企业总资产逾452亿元,总开发面积1300多万平方米,已开发项…...

HarmonyOS给应用添加消息通知
给您的应用添加通知 通知介绍 通知旨在让用户以合适的方式及时获得有用的新消息,帮助用户高效地处理任务。应用可以通过通知接口发送通知消息,用户可以通过通知栏查看通知内容,也可以点击通知来打开应用,通知主要有以下使用场景…...

【C语言】cache和程序访问的局部性对程序性能的影响
文章目录 1.源程序比较其性能影响2.内存分配(1)静态存储区(static):(2)栈区(stack):(3)堆区(heap&…...
数字棱形(课程F)
输入1个整数N,输出N行的如下形状的数字棱形。 例如:N4时: ___1 __222 _33333 4444444 _33333 __222 ___1 (注:上面使用下划线’_’表示空格,以避免看不清造成误解) 输入格式 第一行1个正整数:N࿰…...

如何查看PHP信息
创建一个 PHP 文件,比如 info.php,在其中添加以下代码: <?php phpinfo(); ?>访问这个文件(例如,在浏览器中输入 http://localhost/info.php),它会显示 PHP 的所有配置信息。在这个页面…...
Vue3+ts实现页面跳转及参数传递
## 列表页 <script lang"ts" setup> import { reactive, toRefs } from vue // 1 引入useRouter路由信息方法 import { useRouter } from vue-router // 2 获取实例 const router useRouter()const gotoDetail (index: string) > {router.push({path: …...

日志框架Log4j、JUL、JCL、Slf4j、Logback、Log4j2
1. JAVA日志框架 1.1 为什么程序需要记录日志 我们不可能实时的24小时对系统进行人工监控,那么如果程序出现异常错误时要如何排查呢?并且系统在运行时做了哪些事情我们又从何得知呢?这个时候日志这个概念就出现了,日志的出现对系…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...

2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...