leetcode - 双指针问题
文章目录
前言
题1 移动零:
思路:
参考代码:
题2 复写零:
思考:
参考代码:
题3 快乐数:
思考:
参考代码:
题4 盛最多水的容器:
思考:
参考代码:
题5 有效三角形的个数:
思考:
参考代码:
题6 查找总价格为目标值的两个商品:
思考:
参考代码:
题7 三数之和:
思考:
参考代码:
题8 四数之和:
总结
前言
路漫漫其修远兮,吾将上下而求索;
题1 移动零:
283. 移动零 - 力扣(LeetCode)
提取题干意思:
思路:
数组划分类题型(数组分块):给了我们一个数组,并且制定了一个规则,让我们在这个规则下将该数值划分为若干个区间
本题:
利用双指针,指针cur 从左往右遍历扫描数组,指针dest指向已处理区域非零元素最后一个位置,图解如下:
相当于指针cur、dest 将数据划分为了三段:[0,dest] 为非0的数据区域、[dest+1 , cur-1] 为0的数据区域,[cur,n-1] 为待扫描的数据区域(其中n表示数据个数);
流程:eg. nums = [0,1,0,3,12]
思路总结:
注:双指针思想是快排中最核心的思想;虽可以解决快排问题,但是当数据量特别大的时候(例如相同的数据很多时),该方法的时间复杂度就接近N^2,因此快排不能解决比较恶心的数据(重复的数据多);
参考代码:
void moveZeroes(vector<int>& nums) {int n = nums.size();int cur = 0, dest = -1;while(cur<n){if(nums[cur]){++dest;swap(nums[dest] , nums[cur]);}cur++;}}
优化 - cur 的遍历可以使用范围for,代码如下:
void moveZeroes(vector<int>& nums) {int cur = 0;for(auto& e:nums){if(e) {swap(e , nums[cur]);cur++;}}}
题2 复写零:
1089. 复写零 - 力扣(LeetCode)
提取题干意思:
思考:
我们先思考一下,异地操作(借助于其他空间)如何实现:
需要一个指针cur在旧数组上遍历,一个指针dest在新数组上遍历,当cur 遇到了0 就让dest 写两个0,cur 遇到非0,就让dest 写这个数据;图解如下:
Q1:是否可以从左往右直接使用双指针?
- 本题不行,因为遇见0要在原数组上写两个0,会覆盖掉后面的数据;但是如果是删除值为val 的题,就可以这么做;
Q2:既然从左往右不可行,那么从右往左是否可行呢?
从右往左的话,就需要找到cur 最后一个所要“复写”的位置,如何找?
- 这与整个数组中0的个数有关系,可以先利用双指针(cur,dest)从左往右遍历(cur遇到0,dest走两步,非0dest走一步;当cur 走到最后一个数据或者dest 走到最后一个的时候,cur 指向的位置就是最后一个所要“复写”的位置),找到最后一个所要复写的位置,然后此时cur 、dest 的位置就是从右往左复写数据时的位置,思路图如下:
注:dest 指向有效数据的结尾,初始化为-1;cur 初始化为0;
但是,如果当cur 指向0,而dest 往后走两步可能就会越界,如果dest 越界了;而此时cur 、dest 的位置会作为从右往左复写数据时的位置,但是dest 已经越界了,故而这是有问题的;
解决方法:在找位置结束后判断dest 是否合法(dest小于等于n-1就是合法的范围 ,但是dest 如果越界是一定等于n);如果合法什么都不做,如果不合法,dest = n-1 ,cur--;arr[n-1] = 0,如下图:
即,在找最后一个所要复写的位置的时候,有三种情况回导致循环结束:
参考代码:
void duplicateZeros(vector<int>& arr){int n = arr.size();int cur = 0, dest = -1;//先从左往右遍历,找到cur 指向的最后一个数据while(cur<n){if(arr[cur]==0) dest+=2;else ++dest;//在此过程中dest 可能会越界//在cur 自增前判断dest 是否越界if(dest >= n-1) break;//因为n-1 是最后一个有效位置 cur++;}//边界情况处理,dest 越界了一定是为nif(dest==n){arr[n-1] = 0;dest-=2;--cur;}//从先有的cur dest 的位置进行复写操作while(cur>=0){if(arr[cur]==0){arr[dest--] = 0;arr[dest--] = 0;}else{arr[dest--] = arr[cur];}cur--;}}
题3 快乐数:
202. 快乐数 - 力扣(LeetCode)
提取题干意思:
思考:
根据例子,画图思考:eg. 19 、2
对于19,最后得到是1在循环,故而返回的是true;对于2,最后得到的不是1的循环,所以返回false;
要么最后是1,陷入1的循环;要么不是1但是最后陷入一个循环之中
图解是否感觉有点熟悉?是不是有一点像链表,如果转换成链表,就是判断这链表环中的值即可(因为一旦有1,就一定是1为一个单独的循环);而在链表 - 判断链表是否有环,是用快慢双指针来解决;
可以将本题抽象成链表,一个数变化成一个数可以抽象成这些数串联了起来;并且在本题中不用判断是否有环,只需要判断环中的值便可;
需要注意的是,slow 初始化为第一个数据的位置,fast 初始化为slow 的下一个位置;
只需要判断这两个值相遇的值是不是1即可,是1就返回true ,不是1则返回false;
在这个过程中是一定成环的;
注:
1、在带环的链表中,快慢双指针一定会相遇,并且一定会在环中相遇;
2、本题中虽然不像链表中是一个一个结点,只是一个一个的数 , 我们也可以让数来充当“指针”;不要被指针这个词限制了思维,此处所讲的指针并不是真正的指针,而是在数组中使用双指针的时候可以用数组下标来充当指针,因此“双指针”只是一种思想;
本题题干中:,所以就一定回成环,但是如果题干如果没有给这个提示呢?
那么分析地时候,就会分析出第三种情况:变下去不会成环;存在不成环的情况吗?如果题干没有这个提示,我们又该如何解决?
证明:为什么在变化的过程中一定会有环?
我们先来了解一个原理:鸽巢原理(抽屉原理)
注:我们的证明会用到鸽巢原理
取 9999999999 是因为它是 2.1*10^9 同样位数中的最大的数,可以靠它看一下范围;
对于 9999999999 来说,经过“操作”它每一位的和为 9^2*10 = 810,也就是9999999999经过“操作”之后所能变成的最大的数,即对于 9999999999 来说有810 个巢,而 2.1*10^9 小于9999999999,那么 2.1*10^9 经过操作之后的结果一定小于等于9999999999 经过“操作”之后的结果810,即2.1*10^9 的巢得个数一定小于等于810并且大于等于1;
2.1*10^9 的巢得个数:[1,810]
那么一个数如果进行了“操作”大于810 次(操作次数是无限的),必定就会循环,即该数一定成环;(即将大于810 的鸽子放到810 个巢里面,必定有一个巢中的鸽子数量大于1)就可以证明没有第三种情况:变下去不会成环;
经过上述证明,数据在变化的过程中一定会成环;
参考代码:
//获取一个数的每一个位置上的平方和int getbit(int n){int tmp = n, sum = 0;while(tmp){int t = tmp%10;//每一位sum += t*t;//平方和tmp/=10;//迭代}return sum;}bool isHappy(int n) {//通过鸽巢原理可以证明一定成环,所以可以利用快慢双指针来解决这个问题//注意slow 与 fast 的初始化!int slow = n , fast = getbit(n);//当slow 与 fast 相遇的时候,一定在环中相遇,此时只需要判断相遇的值便可while(slow!=fast){//slow 一次走一步//fast 一次走两部slow = getbit(slow);fast = getbit(fast);fast = getbit(fast);}if(slow == 1) return true;else return false;}
可以优化一下上面的参考代码,优化代码如下:
//获取一个数的每一个位置上的平方和int getbit(int n){int tmp = n, sum = 0;while(tmp){int t = tmp%10;//每一位sum += t*t;//平方和tmp/=10;//迭代}return sum;}bool isHappy(int n) {//通过鸽巢原理可以证明一定成环,所以可以利用快慢双指针来解决这个问题//注意slow 与 fast 的初始化!int slow = n , fast = getbit(n);//当slow 与 fast 相遇的时候,一定在环中相遇,此时只需要判断相遇的值便可while(slow!=fast){//slow 一次走一步//fast 一次走两部slow = getbit(slow);fast = getbit(getbit(fast));}return slow==1;}
题4 盛最多水的容器:
11. 盛最多水的容器 - 力扣(LeetCode)
数据范围:
例子:
思考:
解法一:暴力解法
将所有两两组合的情况均列举出来,找到其中的最大值即可;此处的数据量约有 10万,使用暴力解法的时间复杂度为 O(N^2) ,一定会超时的,不过此处我们还是尝试一下用暴力解法是否能过:
测试用例能通过,但是提交之后:
解法二:利用单调性使用双指针
为什么会想到用单调性?
- 如果想要找到两数相乘再乘以其底面积的最大值,一定是从左边区域中找一个最大的乘以右边区域中最大的数;使用双指针一个从左边开始,一个从右边开始,谁小谁就往自己所在的方向移动;而如果有一个木桶,它的板高度不一样,它所能所能存多少水是由最短的板决定的,所以我们该用短板才会有效果,而桶底也是变化的,所以还需要一个变量来记录体积;
例子:
思路总结:定义两个指针left right ,根据这两个指针指向的数据,记录计算出来的体积,谁小谁移动,循环下去更新得到的最大值;循环条件:left<right;
参考代码:
int maxArea(vector<int>& height) {//体积由短板决定int left = 0 , right = height.size()-1 ,ret = INT_MIN;while(left<right){//体积 = 短板长度*底面积int v = (height[left]<height[right]?height[left] : height[right]) * (right-left);ret = max(ret , v);//谁小谁移动if(height[left]>height[right]) right--;else left++;}return ret;}
题5 有效三角形的个数:
611. 有效三角形的个数 - 力扣(LeetCode)
题干:
数据范围:
例子:
思考:
本题无非就是枚举出所有的三个数,然后判断这三个数能否组成三角形;
Q:如何判断三个数能否构成三角形?
- 首先会想到的是“两边之和大于第三边”,让三个数两两组合然后与第三个数比较,看是否符合就行,但是这种判断方式需要判断三次,效率上有点低,有没有高效点的判断方法?
第二种判断方法:让较小两边相加与最长边比较,如果是大于则就可以构成三角形;
因为最长边一定是大于较小边的(另外两个情况),所以只要保证让较小两边相加大于最长边便可,图解如下:
而对于枚举,首先我们一定会想到的是暴力解法,利用循环枚举出所有的情况,然后判断,这种方法的时间复杂度为O(N^3),先试一下暴力解法能否通过:
使用暴力解法,测试用例可以通过,但是提交:
不能使用暴力解法解决,还能怎么做?
我们前面曾说,判断两个数能够构成三角形,如果得到了这三个数的大小关系,可以拿较小的两个数与最大的那一个数进行比较,不可能每次拿到三个数就先比较大小吧?暴力枚举依然是个痛处,既然在比较的时候就要知道数据的大小关系,那么我们可以先对数据进行排序,利用数据的单调性以及三指针;
- 当 b + c > a 时(即 b 和 c 指向的数据之和大于 a 指向的数据),这三个数必定可以构成三角形。此时,区间 [b+1, c-1] 内的数据均大于 b,且与 c 相加后仍满足大于 a 的条件,那么就有(c-1-b+1)个数符合要求,利用变量记录;然后 c 减 1,继续在下一个区间进行判断
- 当 b + c < a 时(即 b 和 c 指向的数据之和小于 a 指向的数据),这三个数无法构成三角形。此时,区间 [b+1, c-1] 内的数据均小于 c 指向的数据,不符合要求,无需记录,直接让 b 加 1,继续在下一个区间中寻找符合条件的组合。
最大的数a 从右往左遍历,b初始化为0,c初始化为a-1;
这就是解法二:利用单调性,使用双指针方法来解决问题,稍微总结一下:
- 1、先固定最大的数
- 2、在最大的数的左区间中,使用双指针算法,快速统计出符合要求的三元组的个数;
举个例子:
参考代码:
int triangleNumber(vector<int>& nums) {//先对数据进行排序处理sort(nums.begin() , nums.end());int n = nums.size();int a = n-1 , ret = 0;//指向最大的指针for( ; a>=2;a--){int b = 0, c = a-1;//让较小的两个while(b<c){if(nums[b]+nums[c]>nums[a]) //b->[b,c-1] 区间中的数据均合理 {ret+=(c-1-b+1);c--;//去下一个区间}else //不符合要求,那么c->[b+1,c] 中的均不符合{b++;}}}return ret;}
题6 查找总价格为目标值的两个商品:
LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)
题目:
数据范围:
例子:
思考:
方法一:暴力解法
将所有的两个数的组合列举出来然后进行比较
伪代码:
可以试一下用暴力解法能否通过算法:
提交:
暴力解法不行;
方法二:题干中说过price 数组中的数据为升序,我们可以利用好单调性;最先想到的可能是二分算法,但是此处不推荐使用二分,我们可以利用单调性+双指针来解决;
设置两个指针:left 与right , 让left 指向最左的数据,让right 指向最大的数据,如果left + right 的结果大于 target ,那么right--;如果left + right 的结果小于target 那么left++;图解如下:
总结算法逻辑:
参考代码:
vector<int> twoSum(vector<int>& price, int target){//利用数据的单调性+双指针int n = price.size();int left = 0, right = n-1;while(left < right){if(price[left]+price[right] > target) right--;else if(price[left]+price[right] < target) left++;else return {price[left] , price[right]};}//没有找到,返回空return{};}
题7 三数之和:
15. 三数之和 - 力扣(LeetCode)
题干如下:
数据范围:
例子:
思考:
即在数组中找到三个不重复的数据让其相加为0;
根据前面做过的题的经验,我们可以先将数据进行排序处理;
Q:如何让找到的三个数据不重复呢?
- 可以首先将nums 中的数据进行去重处理,利用set就可以了;
解法一:暴力解法:排序 + 暴力枚举 + 利用set 进行去重
此处就不验证暴力解法是否能通过了,数据量有10万,时间复杂度为O(N^3) 的算法一定会超时;
解法二:排序 + 固定一个数a ,利用双指针找到何为-a 的两个值
这样的话,”利用双指针找到何为-a 的两个值“ 的思路就与题6中的思路非常像;
Q:那么去重呢?
- 笔试中可以利用容器set进行去重,但是在面试中不推荐这么做;本题,我们开始就对数据进行了排序处理,那么相同的数据就已经放在了一起;当我们找到了一个结果的时候left 和 right 该如何移动?left 和 right 要跳过与当前所指数相同的重复的数据,继续缩小空间继续查找,同样的,我们固定的数a 也需要进行去重处理,当使用完一轮双指针算法之后,a 也需要跳过重复的数据;
要做到不重不漏;
参考代码:
vector<vector<int>> threeSum(vector<int>& nums) {//首先先对数组进行排序sort(nums.begin(), nums.end());int n = nums.size();vector<vector<int>> ret;for(int i = 0 ;i< n; ){int left = i+1, right = n-1;while(left < right){int target = -nums[i];int sum = nums[left] + nums[right];if(sum > target) right--;else if(sum < target) left++;else{ret.push_back({nums[i], nums[left] , nums[right]});left ++ ,right--;//去重while( left < right && nums[left] == nums[left-1]) left++;while( left < right && nums[right] == nums[right+1]) right--;}}//一轮双指针结束之后,还要对固定的数进行去重处理++i;while(i<n && nums[i] == nums[i-1]) ++i;}return ret;}
题8 四数之和:
18. 四数之和 - 力扣(LeetCode)
题干:
数据范围:
例子:
思考:
本题的解题思路非常浅显:找到4个数 + 判断是否相加为target
找数就有讲究了,要么暴力枚举,要么使用比较巧妙的方法,同样的,本题要求不包含重复的数据,我们可以考虑使用set 去重;
通过数据范围就知道,我们要使用long long ;
解法一:排序 + 暴力解法 + 利用set去重
本题的数据量很大,并且要暴力枚举出4个数,实践复杂度非常高,一定会超时,此处就不演示了;
解法二:排序 + 双指针
可以参考上题三数之和的思路;
首先是将数据进行排序,利用数据有序的特点可以提高效率;然后是固定一个数,再固定一个数,剩下两个数利用双指针;可以理解为,我们先固定一个数a,那么题目就变成在除了固定的的这个数中找和为 (target-a)的三个数:
最后需要做到“不重不漏”,本题会设置三个循环,两个循环用来固定两个数,一个循环适用于双指针,这三个循环都需要关注去重处理(如果不用set 去重的话);而关于不漏,在双指针查找的过程中,我们要在left 和 right 中找到和为目标值时,不能直接结束当前的双指针查找循环,而是要left++,right-- 且left<right ,继续查找下去;
初次尝试:;
计算目标值的时候,记得用long long!
参考代码:
vector<vector<int>> fourSum(vector<int>& nums, int target) {//首先对数据进行排序sort(nums.begin() , nums.end());int n = nums.size();vector<vector<int>> ret;//固定数afor(int i = 0; i<n; ){//固定数bfor(int j = i+1;j<n; ){long long t = ( long long)target - nums[i] -nums[j];//双指针查找int left = j+1,right = n-1;while(left < right){int sum = nums[left] + nums[right];if(sum > t) right--;else if(sum < t) left++;else{//将数据放入数组中ret.push_back({nums[i] , nums[j] , nums[left] , nums[right]});//去重left++,right--;while(left < right && nums[left] == nums[left-1]) left++;while(left < right && nums[right] == nums[right+1]) right--;}}//固定的第二个数的去重++j;while(j<n && nums[j] == nums[j-1])j++;}//固定的第一个数的去重++i;while(i<n && nums[i] == nums[i-1])i++;}return ret;}
总结
双指针题单如下,可以自己练习:
- 283.移动零
- 1089. 复写零
- 202. 快乐数
- 11. 盛最多水的容器
- 611. 有效三角形的个数
- LCR 179. 查找总价格为目标值的两个商品
- 15. 三数之和
- 18. 四数之和
经过以上练习,我们应该可以显然地感受到这类题的特点:从两端向中间出发,逐渐缩小数据范围,必要时,还可以借助于数据的单调性一起使用;借助于单调性会极大地提高代码的效率;
相关文章:

leetcode - 双指针问题
文章目录 前言 题1 移动零: 思路: 参考代码: 题2 复写零: 思考: 参考代码: 题3 快乐数: 思考: 参考代码: 题4 盛最多水的容器: 思考:…...

人工智能之数学基础:二次型
本文重点 二次型作为线性代数领域的重要概念,架起了代数方程与几何分析之间的桥梁。从古典解析几何中的圆锥曲线方程到现代优化理论中的目标函数,二次型以其简洁的数学表达和丰富的结构特性,在数学物理、工程技术和经济金融等领域发挥着不可替代的作用。 二次型的基本概念…...
存储过程补充——流程控制语句详解
文章目录 1. 条件判断语句1.1 分支结构之 IF1.2 分支结构之 CASE 2. 循环语句2.1 循环结构之LOOP2.2 循环结构之WHILE2.3 循环结构之REPEAT 3. 跳转语句3.6 跳转语句之LEAVE语句3.7 跳转语句之ITERATE语句 在数据库管理系统中,存储过程是一种强大的工具,…...

【Unity笔记】实现支持不同渲染管线的天空盒曝光度控制组件(SkyboxExposureController)——参数化控制
写在前面 在Unity中,天空盒(Skybox)不仅承担视觉上的背景作用,更是场景环境光照与氛围塑造的重要组成部分。不同时间、天气、场景转换等,都需要灵活调整天空的亮度。而**曝光度(Exposure)**就是…...

Docker 使用与部署(超详细)
目录 引入 入门使用 部署对比 镜像仓库 命令解释 基础 常见命令 示例 数据卷的使用 数据卷的概念 数据卷的使用 挂载本地目录文件 镜像 结构 Dockerfile 容器网络 部署 DockerCompose 语法 编辑 基础命令 引入 当我们在 Linux 上部署一个集成了很多中间件…...

CSS实现图片垂直居中方法
html <div class"footer border-top-row"><div class"footer-row"><span class"footer-row-col01">制单人:{{ printData[pageIndex - 1].rkMaster.makerName}}<img :src"getPersonSignImgSrc(printData[pa…...
C#实现Socket通信:基于TCP/IP协议的网络编程
TCP/IP网络模型 最上层的是应用层,也就是我们日常可以接触到的,它会给数据添加对应的头部,并传输给传输层,应用层是我们日常会接触到的,比如HTTP,FTP,Telnet,DNS,SMTP。…...
基于C++的IOT网关和平台7:github项目ctGateway设备协议开发指南
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。 源码指引:github源码指引_初级代码游戏的博客-CSDN博客 系…...
大数据实时数仓的数据质量监控解决方案
实时数仓不仅仅是传统数据仓库的升级版,它更强调数据的实时性、流动性和高可用性,通过对海量数据的即时处理和分析,为企业提供近乎实时的洞察力。这种能力在金融、零售、制造、互联网等行业中尤为关键,例如,电商平台可以通过实时数仓监控用户行为,动态调整推荐算法;金融…...

Python+Scrapy跨境电商爬虫实战:从亚马逊/沃尔玛数据采集到反爬攻克(附Pangolin API高效方案)
从零实战到反爬攻克,揭秘跨境数据抓取全流程与Pangolin Scrape API终极方案 在当今数据驱动的跨境电商时代,谁掌握了优质的市场数据,谁就掌握了成功的关键。随着全球电商市场规模持续扩大(据Statista最新报告显示,2025…...
简单快速的浮点数转字符串算法,适合单片机环境
目的是在OLED 屏幕上显示浮点数,有几个设计要求: 我已经有一个现成的能显示整数的函数,希望尽量复用;尽量不使用除法;不需要考虑小数四舍五入的问题; 我觉得小数四舍五入其实很多时候没什么用处ÿ…...
c++中构造对象实例的两种方式及其返回值
c中,构造对象实例有两种方式,一种返回对象实例,一种返回该对象实例的指针。如下所示: 一、两种返回值 RedisConn conn1; //得到实例conn1;RedisConn *conn2 new RedisConn();//得到指针conn2;RedisConn conn3 new RedisConn()…...
Python实例题:Python操作excel自动化开发
目录 Python实例题 题目 安装依赖库 示例代码 代码解释 写入 Excel 文件: 读取 Excel 文件: 修改 Excel 文件: 运行思路 注意事项 Python实例题 题目 Python操作excel自动化开发 安装依赖库 pip install openpyxl示例代码 imp…...

【日撸 Java 三百行】Day 7(Java的数组与矩阵元素相加)
目录 Day 7:Java 的数组与矩阵元素相加 一、基本知识 二、矩阵的建立与基本计算 三、代码及测试 拓展:Arrays类详解 小结 Day 7:Java 的数组与矩阵元素相加 Task: 矩阵的赋值.二重循环. 一、基本知识 在学习 Java 中的数组与矩…...

【Python】常用命令提示符
Python常用的命令提示符 一、Python环境基础命令【Windows】 于Windows环境下,针对Python,在CMD(命令提示符)常用的命令以及具体用法,怎么用; 主要包含:运行脚本、包管理、虚拟环境、调试与…...

vite:npm 安装 pdfjs-dist , PDF.js View 预览功能示例
pdfjs-dist 是 Mozilla 的 PDF.js 库的预构建版本,能让你在项目里展示 PDF 文件。下面为你介绍如何用 npm 安装 pdfjs-dist 并应用 pdf.js 和 pdf.worker.js。 为了方便,我将使用 vite 搭建一个原生 js 项目。 1.创建项目 npm create vitelatest pdf-v…...

【开源版】likeshop上门家政系统PHP版全开源+uniapp前端
一.系统介绍 likeshop_上门家政系统,PHP版本更新至2.1.1最新版,全开源,适用于上门家政场景,系统拥有用户端、师傅端、无论运营还是二开都是性价比极高的100%开源家政系统。 二.搭建环境-教程 系统环境:CentOS、 运行…...
html object标签介绍(用于嵌入外部资源通用标签)(已不推荐使用deprecated,建议使用img、video、audio标签)
文章目录 HTML <object> 标签详解基本语法与核心属性关键属性解析1. **data**2. **type**3. **width & height**4. **name** 嵌入不同类型的资源1. **嵌入图像**2. **嵌入音频**3. **嵌入视频**4. **嵌入 PDF** 参数传递与回退内容**参数(<param>&a…...

MySQL 8.0 OCP 英文题库解析(一)
Oracle 为庆祝 MySQL 30 周年,从 2025.04.20 ~ 2025.07.31 之间,所有人均可以免费考取 MySQL OCP 认证。从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证,省1700多RMB&…...

路由器断流排查终极指南:从Ping测试到Wireshark抓包5步定位法
测试路由器是否出现“断流”(网络连接间歇性中断),需通过多维度排查硬件、软件及外部干扰因素。以下是详细步骤指南: 一、基础环境准备 设备连接 有线测试:用网线将电脑直接连接路由器LAN口,排除WiFi干扰。…...
【Python零基础入门系列】第1篇:Python 是什么?怎么装环境?推荐哪些 IDE?
各位网友们,欢迎来到我的 Python 学习专栏! 前两天看到新闻英伟达为 CUDA 添加原生 Python 支持,意味着开发者可直接用 Python 操作 GPU,加速 AI 和高性能计算,降低门槛,让 Python 的应用范围更广、能力更强。 一直想写一系列文章教知友们从零开始学会 Python 编程,目…...
Spring Boot3 实现定时任务 每10分钟执行一次,同时要解决分布式的问题 区分不同场景
在Spring Boot 3中实现分布式定时任务,确保多实例环境下任务仅执行一次,可以采用以下方案: 方案一:Redis分布式锁(推荐) import org.springframework.data.redis.core.StringRedisTemplate; import org.sp…...

04 基于 STM32 的时钟展示程序
前言 我们经常会看到 各个场合下面有 基于数码管 的时钟程序 比如 在车站, 教室, 办公室 等等 各个场合都有 然后 这里就是做一个 简单的 时钟程序 展示程序 测试用例 每一秒钟更新时间, 然后 迭代更新 天, 时, 分 等等 然后 主流程 基于 天, 时分秒 渲染数码管 #incl…...

n8n工作流自动化平台:生成图文并茂的分析报告之Merge节点详细说明
1.成果展示 1.1工作流示意图 1.2成果 数据都是造得 2Merge节点 2.1Mode 通过选择模式指定合并节点应如何组合来自不同数据流的数据 2.1.1Append 保存所有输入的数据。选择一个输入数量,逐一输出每个输入的项目。节点等待所有连接的输入的执行。 2.1.2Combine 2.1.2.1Co…...

华为设备MSTP
一、MSTP核心理论 1. 基本概念 MSTP定义:MSTP(Multiple Spanning Tree Protocol)是一种基于实例的生成树协议,支持多个生成树实例(MSTI),每个实例对应一组VLAN,实现不同VLAN流量的负…...
华为银河麒麟 V10(ARM)系统软件部署全攻略:Redis、RabbitMQ、MySQL 等集群搭建指南
一、Redis 集群部署(主从 哨兵模式) 1. 环境准备 系统:华为银河麒麟 V10(ARM64)节点:3 台服务器(1 主 2 从 3 哨兵) 2. 安装包下载 bash # 华为镜像站 wget https://update.c…...

Loly: 1靶场渗透
Loly: 1 来自 <Loly: 1 ~ VulnHub> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182,靶场IP192.168.23.241 3,对靶机进行端口服务探测 n…...

Linux系统入门第十一章 --Shell编程之函数与数组
一、Shell函数 1、函数的用法 Shell函数可用于存放一系列的指令。在Shell脚本执行的过程中,函数被置于内存中,每次调用函数时不需要从硬盘读取,因此运行的速度比较快。在Shell编程中函数并非是必须的元素,但使用函数可以对程序进…...
AWS VPC架构师指南:从零设计企业级云网络隔离方案
一、VPC核心概念解析 1.1 核心组件 VPC:逻辑隔离的虚拟网络,可自定义IPv4/IPv6地址范围(CIDR块) 子网(Subnet): 公有子网:绑定Internet Gateway(IGW)&#…...

聊聊自动化办公未来趋势
1. 自动化办公未来趋势 1.1 智能化与AI融合加深 随着人工智能技术的不断成熟,其在自动化办公中的应用将更加广泛和深入。未来,办公软件将具备更强的智能交互能力,能够理解自然语言指令,自动完成复杂的任务,如文档编辑…...