【算法专题】双指针
双指针
- 双指针
- 1. 移动零
- 2. 复写零
- 3. 快乐数
- 4. 盛水最多的容器
- 5. 有效三角形的个数
- 6. 和为s的两个数字
- 7. 三数之和
- 8. 四数之和
双指针
常见的双指针有两种形式,⼀种是对撞指针,⼀种是左右指针。
- 对撞指针:⼀般用于顺序结构中,也称左右指针。
- 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。
- 对撞指针的终止条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环),也就是:
left == right (两个指针指向同⼀个位置)
left > right (两个指针错开)
- 快慢指针:其基本思想就是使用两个移动速度不同的指针在数组或链表等序列结构上移动。这种方法对于处理环形链表或数组非常有用。
其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。快慢指针的实现方式有很多种,最常用的⼀种就是:
- 在⼀次循环中,每次让慢的指针向后移动⼀位,而快的指针往后移动两位,实现⼀快⼀慢
下面我们看练习题目:
1. 移动零
题目链接 -> Leetcode -283.移动零
Leetcode -283.移动零
题目:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0, 1, 0, 3, 12]
输出 : [1, 3, 12, 0, 0]
示例 2 :
输入 : nums = [0]
输出 : [0]
提示 :
- 1 <= nums.length <= 10^4
- 2^31 <= nums[i] <= 2^31 - 1
其思路的本质是快排的思想:数组划分区间 - 数组分两块;我们可以用⼀个 cur 指针来扫描整个数组,另⼀个 dest 指针用来记录非零数序列的最后⼀个位置。根据 cur 在扫描的过程中,遇到的不同情况,分类处理,实现数组的划分。在 cur 遍历期间,使 [0, dest] 的元素全部都是非零元素, [dest + 1, cur - 1] 的元素全是零。 代码如下:
class Solution {public:// 双指针void moveZeroes(vector<int>& nums){// dest 是最后一个非零元素的下标int cur = 0, dest = -1;while (cur < nums.size()){// nums[cur] 不为零先++dest,再交换两个值 if (nums[cur]){swap(nums[++dest], nums[cur]);}cur++;}}};
2. 复写零
题目链接 -> Leetcode -1089.复写零
Leetcode -1089.复写零
题目:给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。
示例 1:
输入:arr = [1, 0, 2, 3, 0, 4, 5, 0]
输出:[1, 0, 0, 2, 3, 0, 0, 4]
解释:调用函数后,输入的数组将被修改为:[1, 0, 0, 2, 3, 0, 0, 4]
示例 2:
输入:arr = [1, 2, 3]
输出:[1, 2, 3]
解释:调用函数后,输入的数组将被修改为:[1, 2, 3]
提示:
1 <= arr.length <= 10^4
0 <= arr[i] <= 9
思路:如果从前向后进行原地复写操作的话,由于 0 的出现会复写两次,导致没有复写的数被覆盖掉。因此我们选择「从后往前」的复写策略。但是从后向前复写的时候,我们需要找到最后⼀个复写的数,因此我们的大体流程分两步:
i. 先找到最后⼀个复写的数;
ii. 然后从后向前进行复写操作
代码如下:
class Solution {public:void duplicateZeros(vector<int>& arr){// 先用 dest 指针模拟一遍复写,当 dest == n - 1,dest 最终的位置就是复写零后数组的最终形式,可以用 cur 位置的元素覆盖它int cur = 0, dest = -1, n = arr.size();while (cur < n){if (arr[cur] == 0) dest += 2;else dest++;if (dest >= n - 1) break;cur++;}// 当 dest > n - 1 最后dest肯定走了两步,即最后复写的元素一定是零,所以直接将最后一个元素改成0后,dest向前走两步,cur向前走一步if (dest == n){arr[n - 1] = 0;cur--, dest -= 2;}// 正常的覆盖while (cur >= 0){if (arr[cur] == 0){arr[dest--] = 0;arr[dest--] = 0;cur--;}else{arr[dest--] = arr[cur--];}}}};
3. 快乐数
题目链接 -> Leetcode -202.快乐数
Leetcode -202.快乐数
题目:编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
示例 1:
输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
示例 2:
输入:n = 2
输出:false
提示:
1 <= n <= 2^31 - 1
思路:为了方便叙述,将「对于⼀个正整数,每⼀次将该数替换为它每个位置上的数字的平方和」这⼀个操作记为 x 操作;
题目告诉我们,当我们不断重复 x 操作的时候,计算⼀定会「死循环」,死循环的方式有两种:
▪ 情况⼀:⼀直在 1 中死循环,即 1 -> 1 -> 1 -> 1…
▪ 情况⼆:在历史的数据中死循环,但始终变不到 1
由于上述两种情况只会出现⼀种,因此,只要我们能确定循环是在「情况⼀」中进行,还是在「情况⼆」中进行,就能得到结果。
代码如下:
class Solution {public:// 计算每个位上的平方相加,即进行快乐数的计算int bitNum(int n){int sum = 0;while (n > 0){int x = n % 10;sum += x * x;n /= 10;}return sum;}bool isHappy(int n){// 定义快慢指针,慢指针一定可以追上快指针,最后只需判断他们相遇时的结果是否是1即可int slow = n, fast = bitNum(n);while (slow != fast){slow = bitNum(slow);fast = bitNum(bitNum(fast));}if (slow == 1) return true;return false;}};
4. 盛水最多的容器
题目链接 -> Leetcode -11.盛最多水的容器
Leetcode -11.盛最多水的容器
题目:给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是(i, 0) 和(i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
示例 1:
输入:[1, 8, 6, 2, 5, 4, 8, 3, 7]
输出:49
解释:图中垂直线代表输入数组[1, 8, 6, 2, 5, 4, 8, 3, 7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入:height = [1, 1]
输出:1
提示:
n == height.length
2 <= n <= 10^5
0 <= height[i] <= 10^4
思路:对撞指针,两个指针分别定义在数组的头和尾,假设是 left 和 right,并假设 left < right;此时 left 决定了盛水的容量,此时如果我们舍去 left 并使 left++,有可能下一条边比 left 更长,此时的盛水容量有可能变大;但是如果我们舍去 right,并使 right–,就算下一条边更长,left 还是决定了盛水的容量,所以盛水的容量不变或者减小;所以我们不能舍去长的那一条边,我们可以大胆舍去短的那一边;当我们不断重复上述过程,每次都可以舍去大量不必要的枚举过程,直到 left 与 right 相遇。期间产生的所有的容积里面的最⼤值,就是最终答案。
代码如下:
class Solution {public:int maxArea(vector<int>& height){int n = height.size(), ret = 0;// 定义双指针int left = 0, right = n - 1;while (left < right){// 盛水是要看最短的那边,所以相乘用最短的板ret = max(ret, (min(height[left], height[right]) * (right - left)));// 如果左边短了,左指针往右移;否则右指针往左移if (height[left] < height[right]) left++;else right--;}return ret;}};
5. 有效三角形的个数
题目链接 -> Leetcode -611.有效三角形的个数
Leetcode -611.有效三角形的个数
题目:给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。
示例 1:
输入: nums = [2, 2, 3, 4]
输出 : 3
解释 : 有效的组合是 :
2, 3, 4 (使用第一个 2)
2, 3, 4 (使用第二个 2)
2, 2, 3
示例 2 :
输入 : nums = [4, 2, 3, 4]
输出 : 4
提示 :
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
思路是对数组先排序,每次固定一个数,再使用对撞指针优化;具体的思路参考代码中的注释:
class Solution {public:int triangleNumber(vector<int>& nums){// 先进行排序sort(nums.begin(), nums.end());int ans = 0;// 先固定一个数for (int i = nums.size() - 1; i >= 2; i--){// 再使用双指针枚举另外两个数// 其中left在从小的开始枚举,right从大的开始枚举int left = 0, right = i - 1;while (left < right){// 如果 nums[left] + nums[right] > nums[i] 说明left到right区间都能和i构成三角形;所以ans累加上区间内的个数// 累加完后left没必要++了,因为数组是有序的,left都能组成三角形,比left大的肯定可以,所以此时让 right--if (nums[left] + nums[right] > nums[i]){ans += (right - left);right--;}// 否则 left++else{left++;}}}return ans;}};
6. 和为s的两个数字
题目链接 -> Leetcode -剑指 Offer 57.和为s的两个数字
Leetcode -剑指 Offer 57.和为s的两个数字
题目:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
示例 1:
输入:nums = [2, 7, 11, 15], target = 9
输出:[2, 7] 或者[7, 2]
示例 2:
输入:nums = [10, 26, 30, 31, 47, 60], target = 40
输出:[10, 30] 或者[30, 10]
限制:
1 <= nums.length <= 10 ^ 5
1 <= nums[i] <= 10 ^ 6
这道题的思路与上题类似,所以直接给出代码:
class Solution {public:vector<int> twoSum(vector<int>& nums, int target){// 因为数组已经有序,利用有序使用双指针枚举int left = 0, right = nums.size() - 1;while (left < right){if (nums[left] + nums[right] == target) return { nums[left],nums[right] };else if (nums[left] + nums[right] > target) right--;else left++;}return { -1,-1 };}};
7. 三数之和
题目链接 -> Leetcode -15.三数之和
Leetcode -15.三数之和
题目:给你一个整数数组 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]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是[-1, 0, 1] 和[-1, -1, 2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0, 1, 1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0, 0, 0]
输出: [[0, 0, 0]]
解释:唯一可能的三元组和为 0 。
提示:
- 3 <= nums.length <= 3000
- 10^5 <= nums[i] <= 10^5
此题与两数之和类似,与两数之和稍微不同的是,题目中要求找到所有不重复的三元组。那我们可以利用在两数之和那里用的双指针思想,来对我们的暴力枚举做优化:
i. 先排序;
ii. 然后固定⼀个数 a :
iii. 在这个数后⾯的区间内,使用「双指针算法」快速找到两个数之和等于 -a 即可。
但是要注意,这道题里面需要有「去重」操作:
i. 找到⼀个结果之后, left 和 right 指针要「跳过重复」的元素;
ii. 当使用完⼀次双指针算法之后,固定的 a 也要「跳过重复」的元素
代码如下:
class Solution {public:vector<vector<int>> threeSum(vector<int>& nums){// 先对数组排序sort(nums.begin(), nums.end());vector<vector<int>> ret;// 先固定一个数,再使用双指针for (int i = 0; i < nums.size() - 1; i++){// 去重 nums[i] 相同的元素if (i > 0 && nums[i] == nums[i - 1]) continue;int left = i + 1, right = nums.size() - 1;while (left < right){if (nums[left] + nums[right] == -nums[i]){ret.push_back({ nums[left],nums[right],nums[i] });right--, left++;// 去重 left 和 rightwhile (left < right && nums[right] == nums[right + 1]) right--;while (left < right && nums[left] == nums[left - 1]) left++;}else if (nums[left] + nums[right] > -nums[i]){right--;}else{left++;}}// 因为是排序后的数组,如果 nums[i] 大于0,后面的数都比它大,找不到两数相加等于它的负数的数,所以提前跳出环 if (nums[i] > 0) break;}return ret;}};
8. 四数之和
四数之和的做法也和三数之和类似,大家可以自行尝试一下,题目链接 -> Leetcode -18.四数之和
Leetcode -18.四数之和
题目:给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。
请你找出并返回满足下述全部条件且不重复的四元组[nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1, 0, -1, 0, -2, 2], target = 0
输出: [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
示例 2:
输入:nums = [2, 2, 2, 2, 2], target = 8
输出: [[2, 2, 2, 2]]
提示:
1 <= nums.length <= 200
- 10^9 <= nums[i] <= 10^9
- 10^9 <= target <= 10^9
下面直接看代码解析:
class Solution {public:vector<vector<int>> fourSum(vector<int>& nums, int target){sort(nums.begin(), nums.end());vector<vector<int>> ret;int len = nums.size();// 先固定第一个数for (int i = 0; i < len - 3; i++){// 去重1.if (i > 0 && nums[i] == nums[i - 1]) continue;// 固定第二个数int aim1 = target - nums[i];for (int j = i + 1; j < len - 2; j++){// 去重2.if (j > i + 1 && nums[j] == nums[j - 1]) continue;// 使用双指针long long aim2 = (long long)aim1 - nums[j];int left = j + 1, right = len - 1;while (left < right){if (nums[left] + nums[right] > aim2){right--;}else if (nums[left] + nums[right] < aim2){left++;}else{ret.push_back({ nums[i],nums[j],nums[left],nums[right] });left++, right--;// 去重3.while (left < right && nums[left] == nums[left - 1]) left++;while (left < right && nums[right] == nums[right + 1]) right--;}}}}return ret;}};
相关文章:
【算法专题】双指针
双指针 双指针1. 移动零2. 复写零3. 快乐数4. 盛水最多的容器5. 有效三角形的个数6. 和为s的两个数字7. 三数之和8. 四数之和 双指针 常见的双指针有两种形式,⼀种是对撞指针,⼀种是左右指针。 对撞指针:⼀般用于顺序结构中,也称…...

redis运维(七)基础通用命令
一 基础通用命令 备注: 与具体数据类型无关Tab键 自动补全补充: redis 命令是不区分大小写 通用不到 10 个提升逼格的 redis 命令 后续: slowlog、rename-command、monitor、set ① help command 需求: 显示有关redis命令的…...

搜索引擎ElasticSearch分布式搜索和分析引擎学习,SpringBoot整合ES个人心得
ElasticSearch Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elas…...
云原生微服务架构图
云原生微服务架构的具体架构图会根据应用程序的需求、规模和业务场景而有所不同。以下是一个通用的云原生微服务架构图,具体每层的组件可能有所不同: 用户界面层: Web应用或移动应用: 提供用户访问和交互的前端应用。API Gateway&…...

泊车功能专题介绍 ———— AVP系统技术要求之人机交互云平台
文章目录 人机交互车端人机交互车外人机交互灯光交互声音交互 车内人机交互信号装置标示的交互声音交互 场景左右转弯经过让行提示泊入泊出 激活及退出条件激活条件退出条件 场端人机交互V2X交互故障车提醒路口盲区预警弱势交通参与者提醒 场端设施的预警车辆入场车辆故障 APP人…...

精密云工程:智能激活业务速率 ——华为云11.11联合大促倒计时 仅剩3日
现新客3.96元起,下单有机会抽HUAWEI P60 Art,福利仅限双十一,机会唾手可得,立即行动! 双十一购物节来临倒计时,华为云备上多款增值产品,以最优品质迸发冬日技术热浪,满足行业技术应用…...

SpringBoot整合EasyExcel
目录 一、EasyExcel介绍 1、简介 2、常用注解 二、SpringBoot整合EasyExcel 1、基本环境 (1)引入依赖 (2)创建实体类 2、EasyExcel内容读取 (1)创建监听器 (2)测试 3、EasyExcel内容校验 (1)场景描述 (2)EasyExcel监听器 (3)测试 4、EasyExcel内容批量插…...
详解JS遍历数组的十八种方法
for循环 let arr[1,2,3] for(let i0;i<arr.length;i){console.log(arr[i]) }for循环可以遍历数组,它一共有三个参数,第一个参数可以当成数组索引值,想要遍历时候可以设置初始值为0,然后以数组长度为判断依据,如果不…...
Python程序设计基础2
第1关:HUT开学了: # 请在此添加代码 Name = input() # 输入学生的姓名 ########## Begin ########## print("|++++++++++++++++++++++|") print("| |") print("| Welcome to HUT |") print("| …...
域名服务器有哪些类型
域名服务器有哪些类型 随着现在网络的不断发展,越来越多的企业开始使用网络建站,以此来进行营销和推广,而网站在建设过程中需要使用域名和空间,那么域名服务器是什么?下面由给大家说一下。 主域名服务器 负责维护一…...

5.什么是Spring的依赖注入(DI)?IOC和DI的区别是什么
很多人把IOC和DI说成一个东西,笼统来说的话是没有问题的,但是本质上还是有所区别的,希望大家能够严谨一点, IOC和DI是从不同的角度描述的同一件事,IOC是从容器的角度描述,而DI是从应用程序的角度来描述,也…...

Python开源自动化工具Playwright安装及介绍
一个非常强大的自动化项目叫 playwright-python 它支持主流的浏览器,包含:Chrome、Firefox、Safari、Microsoft Edge 等,同时支持以无头模式、有头模式运行,并提供了同步、异步的 API,可以结合 Pytest 测试框架 使用&…...
Nginx生产环境安装配置
不建议使用nginx-1.18.0.tar.gz,因为扫出很多漏洞 上传nginx-1.24.0.tar.gz [rootzonghe01 data]# ll -rw-r--r-- 1 root root 1112471 Oct 26 15:57 nginx-1.24.0.tar.gz [rootzonghe01 data]# pwd /data解押 [rootzonghe01 data]# tar -zxvf nginx-1.24.0.tar…...

「项目阅读系列」go-gin-example star 6.5k!(1)
文章目录 准备工作适宜人群项目信息 项目结构代码阅读主要模块代码主函数模块router 路由模块auth 授权模块数据库 修改文章请求分析其他依赖 总结 准备工作 适宜人群 初学 go 语法,希望了解 go 项目的构建过程和方式。 项目信息 go-gin-example 项目是使用 gin…...
基于轻量级yolov5的瓷砖瑕疵检测系统
该专栏仅支持购买本专栏的同学学习使用,不支持以超级会员、VIP等形式使用,请谅解!【购买专栏后可选择其中一个完整源码项目】 本文是我新开设的专栏《完整源码项目实战》 的第十二篇全源码文章,包含数据集在内的所有资源,可以实现零基础上手入门学习。前面系列文章链接如下…...
Linux:系统基本信息扫描(2)
#网络地址:ip a------------------------------------------------------------- ip a echo "主机名:-------------------------------------------------------" hostnamectl sleep 0.5s echo "#系统基本信息:--------------------------------------------…...
什么是虚拟DOM(Virtual DOM),说说工作原理
虚拟DOM(Virtual DOM)是一种将页面的状态抽象为JavaScript对象表示的概念,用于提高Web应用程序的性能和渲染效率。 虚拟DOM的工作原理如下: 1: 初始渲染:首先,通过JavaScript对象(…...

Kafka的重要组件,谈谈流处理引擎Kafka Stream
系列文章目录 上手第一关,手把手教你安装kafka与可视化工具kafka-eagle Kafka是什么,以及如何使用SpringBoot对接Kafka 架构必备能力——kafka的选型对比及应用场景 Kafka存取原理与实现分析,打破面试难关 防止消息丢失与消息重复——Kafka可…...
基于yolov5模型的200种鸟类检测识别分析系统
该专栏仅支持购买本专栏的同学学习使用,不支持以超级会员、VIP等形式使用,请谅解!【购买专栏后可选择其中一个完整源码项目】 本文是我新开设的专栏《完整源码项目实战》 的第十三篇全源码文章,包含数据集在内的所有资源,可以实现零基础上手入门学习。前面系列文章链接如下…...

JavaScript的学习,就这一篇就OK了!(超详细)
目录 Day27 JavaScript(1) 1、JS的引入方式 2、ECMAScript基本语法 3、ECMAScript 基本数据类型编辑 3.1 数字类型 3.2 字符串 3.3 布尔值 3.4 空值(Undefined和Null) 3.5 类型转换 3.6 原始值和引用值 4、运算符 5、流程控制语句 5.1 分…...

超大规模芯片验证:基于AMD VP1902的S8-100原型验证系统实测性能翻倍
引言: 随着AI、HPC及超大规模芯片设计需求呈指数级增长原型验证平台已成为芯片设计流程中验证复杂架构、缩短迭代周期的核心工具。然而,传统原型验证系统受限于单芯片容量(通常<5000万门)、多芯片分割效率及系统级联能力&#…...
SQL进阶之旅 Day 20:锁与并发控制技巧
【JDK21深度解密 Day 20】锁与并发控制技巧 文章简述 在高并发的数据库环境中,锁与并发控制是保障数据一致性和系统稳定性的核心机制。本文作为“SQL进阶之旅”系列的第20天,深入探讨SQL中的锁机制、事务隔离级别以及并发控制策略。文章从理论基础入手…...
Android LinearLayout、FrameLayout、RelativeLayout、ConstraintLayout大混战
一、为什么布局性能如此重要? 在Android应用中,布局渲染耗时直接决定了界面的流畅度。根据Google官方数据,超过60%的卡顿问题源于布局性能不佳。本文将彻底解析三大传统布局的性能奥秘,并提供可直接落地的优化方案。 二、三大布局…...
rk3588 区分两个相同的usb相机
有时候会插入两个一模一样的usb相机,担心每次启动他们所对应的设备节点 /dev/video* 会变化,所以需要绑定usb口,区分两个相机。把两个相机都插入后,查看usb信息 rootrk3588:/# udevadm info --attribute-walk --name/dev/video0U…...

网络编程之服务器模型与UDP编程
一、服务器模型 在网络通信中,通常要求一个服务器连接多个客户端 为了处理多个客户端的请求,通常有多种表现形式 1、循环服务器模型 一个服务器可以连接多个客户端,但同一时间只能连接并处理一个客户的请求 socket() 结构体 bind() listen() …...

Java建造者模式(Builder Pattern)详解与实践
一、引言 在软件开发中,我们经常会遇到需要创建复杂对象的场景。例如,构建一个包含多个可选参数的对象时,传统的构造函数或Setter方法可能导致代码臃肿、难以维护。此时,建造者模式(Builder Pattern)便成为…...

Mac 安装git心路历程(心累版)
省流版:直接安装Xcode命令行工具即可,不用安Xcode。 git下载官网 第一部分 上网初步了解后,打算直接安装Binary installer,下载完安装时,苹果还阻止安装,只好在“设置–安全性与隐私”最下面的提示进行安…...
如何区分 “通信网络安全防护” 与 “信息安全” 的考核重点?
“通信网络安全防护” 与 “信息安全” 的考核重点可以从以下几个方面进行区分: 保护对象 通信网络安全防护:重点关注通信网络系统本身,包括网络基础设施,如路由器、交换机、基站等,以及网络通信链路和相关设备。同…...

RPA+AI:自动化办公机器人开发指南
RPAAI:自动化办公机器人开发指南 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 RPAAI:自动化办公机器人开发指南摘要引言技术融合路径1. 传感器层:多模态数据接入2. 决策层&…...

思尔芯携手Andes晶心科技,加速先进RISC-V 芯片开发
在RISC-V生态快速发展和应用场景不断拓展的背景下,芯片设计正面临前所未有的复杂度挑战。近日,RISC-V处理器核领先厂商Andes晶心科技与思尔芯(S2C)达成重要合作,其双核单集群AX45MPV处理器已在思尔芯最新一代原型验证系…...