- 博客(38)
- 收藏
- 关注
原创 在Linux系统下实现的内网穿透(FastTunnel)
在当今高度互联的世界中,网络通信的自由与便捷成为了信息社会的基石。然而,网络地址转换(NAT)和防火墙的存在,虽然增强了内部网络的安全性,但也给内外网络的直接通信带来了挑战。内网穿透技术应运而生,它如同一把钥匙,打开了私有网络与外部互联网之间的通道,使得位于私有网络中的服务能够被外部用户访问,极大地扩展了网络服务的应用范围和访问方式。本文将详细介绍内网穿透的原理、配置步骤,以及如何在Linux系统中使用FastTunnel进行内网穿透,实现内外网服务的无缝连接。
2024-07-22 21:41:03
3712
原创 Linux下MySQL的安装部署
MySQL,作为全球最受欢迎的开源关系型数据库管理系统之一,以其卓越的性能、可靠性及广泛的社区支持而闻名。无论是初创企业还是大型跨国公司,MySQL都是构建高效应用和服务的首选数据库解决方案。本文旨在为那些希望在Linux环境中部署MySQL的用户,提供一个全面、详细的安装与配置教程。我们将从基础的软件包下载开始,逐步深入到系统服务脚本的创建,以及如何通过Shell脚本简化安装过程。通过本教程,您将能够掌握MySQL的安装部署。
2024-07-21 23:20:57
6529
原创 Linux系统下Nginx的安装部署(两种方式)
在当今互联网时代,网络服务的稳定性和性能是衡量一个网站或应用成功与否的关键因素之一。Nginx,作为一个强大的开源Web服务器和反向代理服务器,以其卓越的高并发处理能力和高效的资源利用率,成为了众多开发者和企业的首选。无论是在云环境还是在传统的数据中心,Nginx都能够提供出色的性能表现和稳定的运行效果。本文旨在为Linux环境下的开发者和技术运维人员提供一份Nginx安装指南,包括在线二进制部署和离线手动安装两种方式,以及一系列常用的Nginx命令。
2024-07-19 11:01:51
4220
1
原创 力扣(滑动窗口最大值)
这篇文章解析了LeetCode 239题"滑动窗口最大值"的解题思路。文章首先分析题目要求,指出直接遍历每个窗口的暴力解法效率不足。然后详细介绍了一种利用双端队列维护单调递减序列的优化算法,该算法能高效追踪窗口中的最大值候选。文章提供了Java代码实现,并逐步解析了代码逻辑,包括移除过期元素、维护单调队列和记录最大值等关键步骤。最后分析了算法的时间复杂度为O(n),空间复杂度为O(n)。这种方法通过巧妙的数据结构运用,显著提升了算法效率。
2025-08-26 18:00:05
1066
原创 力扣(逆波兰表达式求值)
摘要: LeetCode 150题要求计算逆波兰表达式值。该表达式天然适配栈结构:遇到操作数入栈,遇到运算符则弹出栈顶两个元素(注意顺序)计算后将结果入栈。关键点在于:1)减法和除法需区分操作数顺序;2)除法需向零截断。算法通过遍历tokens数组,利用栈实现运算,时间复杂度O(n),空间复杂度O(n)。代码采用ArrayDeque优化栈操作,并通过字符串长度快速识别运算符提升效率。
2025-08-26 17:56:21
928
原创 力扣(有效括号)
本文解析了LeetCode 20题"有效的括号",提出利用栈结构判断括号匹配的算法。核心思路是将左括号对应右括号入栈,遇到右括号时检查栈顶是否匹配。算法能处理四种不匹配情况:字符串长度为奇数、右括号无对应左括号、括号类型不匹配、左括号未完全匹配。时间复杂度O(n),空间复杂度O(n)。通过这种巧妙转化,将复杂的匹配问题简化为栈操作,高效解决了括号有效性验证问题。
2025-08-25 19:18:59
1250
原创 力扣(用队列实现栈)
这篇文章解析了LeetCode 225题"用队列实现栈"的解题思路,重点介绍了单队列的巧妙实现方法。文章首先分析了题目需求与核心挑战,指出如何用FIFO队列模拟LIFO栈的特性是关键。然后详细阐述了单队列反转操作的核心思想:通过每次push时将新元素入队后,将队列中其他元素依次出队再入队,使新元素移动到队首来实现栈顶操作。最后提供了Java代码实现,并分析了其时间复杂度(push为O(n),其他操作为O(1))和空间复杂度O(n)。该方法相比双队列实现更简洁高效。
2025-08-25 19:12:29
1009
原创 力扣(组合)
本文解析了LeetCode 77题"组合"的回溯解法。题目要求从1到n中找出所有k个数的组合。通过回溯算法遍历所有可能选择,同时采用剪枝优化:当剩余可选数加已选数不足k时跳过后续循环,显著提升效率。代码中使用递归实现回溯,动态维护当前组合,满足条件时存入结果。时间复杂度为O(k×C(n,k)),空间复杂度为O(k+C(n,k))。该解法通过系统选择与撤销操作,结合剪枝策略,高效枚举了所有有效组合。
2025-08-23 18:37:54
823
原创 力扣(全排列)
本文解析了LeetCode 46题"全排列"的回溯算法解法。该问题要求生成不含重复数字数组的所有可能排列,通过回溯算法实现深度优先搜索:选择元素加入排列,递归处理下一位置,回溯时撤销选择。代码使用used数组标记元素使用状态,递归终止条件是排列长度等于数组长度。时间复杂度为O(n×n!),空间复杂度为O(n×n!)。该解法展示了回溯算法在排列组合问题中的经典应用。
2025-08-23 18:34:49
946
原创 力扣(在排序数组中查找元素的第一个和最后一个位置)
本文解析了LeetCode 34题,探讨如何在有序数组中高效查找目标值的起始和结束位置。通过分析原始代码的复杂度问题,提出优化方案:采用两次独立的二分查找,分别定位左边界(第一个等于目标值的位置)和右边界(最后一个等于目标值的位置)。优化后的代码逻辑更清晰,时间复杂度保持O(log n),空间复杂度为O(1)。关键点在于正确处理二分查找的边界条件,先验证左边界有效性,再推导右边界,确保结果准确。
2025-08-22 19:21:44
1339
原创 力扣(字母异位词分组)
摘要: LeetCode 49题要求将字母异位词分组,核心在于高效判断异位词并聚合。通过将字符串排序生成唯一特征作为哈希表键,未排序字符串作为值列表成员,实现O(nk logk)时间复杂度分组。代码利用哈希表快速查找特性,排序后字符串作为分组依据,结果集与哈希表共享引用避免额外存储。该方法巧妙结合排序与哈希表,将复杂异位词判断转化为键值匹配问题,空间复杂度O(nk)。(149字)
2025-08-22 19:18:41
1243
原创 力扣(电话号码的字母组合)
文章摘要 LeetCode 17题"电话号码的字母组合"是一个典型的回溯算法应用。题目要求根据数字字符串生成所有可能的字母组合(如"23"对应"ad","ae"等)。解题关键在于:1)建立数字到字母的映射表;2)使用回溯算法遍历所有组合可能;3)正确处理边界条件。算法通过"选择-递归-撤销"的流程,确保不遗漏任何组合。时间复杂度为O(mⁿ×n),空间复杂度为O(n)。文中提供了Java实现代码,详细解析了回溯
2025-08-19 20:43:27
1026
原创 力扣(最小栈)
本文介绍了LeetCode 155题"最小栈"的高效实现方案。通过自定义链表节点结构,每个节点额外存储当前栈的最小值,使得所有操作(push、pop、top和getMin)的时间复杂度均为O(1)。文章详细解析了链表节点的设计思路,包括哨兵节点的使用、min属性的动态维护等关键实现细节,并提供了完整的Java代码实现及注释。该方案在保证栈基本功能的同时,高效解决了获取最小值的需求,空间复杂度为O(n),n为栈中元素数量。
2025-08-19 20:41:03
726
原创 力扣(分发糖果)
本文解析了LeetCode 135题"分发糖果"的贪心算法解法。题目要求给每个孩子分发糖果,满足相邻孩子中评分高的糖果更多,同时使用最少糖果总数。通过两次遍历的贪心策略:第一次从左到右处理左相邻关系,确保评分高的孩子比左边多;第二次从右到左处理右相邻关系,取当前值和右边值+1的较大值以同时满足两边规则。算法时间复杂度O(n),空间复杂度O(n)。这种方法通过分步优化局部约束,最终达到全局最优解。
2025-08-18 19:53:00
1244
原创 力扣(盛最多水的容器)
本文深入解析了LeetCode第11题"盛最多水的容器"的解题思路。通过双指针法从数组两端向中间遍历,每次移动较短的指针以寻找更大的容器容量,避免了暴力枚举的O(n²)复杂度。文章详细阐述了双指针的选择逻辑、移动策略,并提供了Java代码实现及其执行流程分析。该算法的时间复杂度优化至O(n),空间复杂度为O(1),适用于大规模数据处理。关键在于通过舍弃不可能带来更大容量的情况,实现高效计算最大盛水量。
2025-08-18 19:52:35
729
原创 力扣(最小覆盖子串)
本文解析了LeetCode 76题"最小覆盖子串"的解法。该问题要求在字符串s中找到包含字符串t所有字符的最小子串。文章提出哈希表与滑动窗口的协同策略:通过哈希表统计字符出现次数实现快速匹配,利用滑动窗口动态调整边界范围。详细介绍了算法实现步骤,包括初始化哈希表、窗口伸缩逻辑和匹配条件判断。该解法的时间复杂度为O(m+n),空间复杂度O(m+n),能高效处理字符串匹配问题。关键点在于通过哈希表计数和滑动窗口的动态调整,在保证正确性的同时优化了性能。
2025-08-16 20:35:01
1336
原创 力扣(接雨水)——基于最高柱分割的双指针
本文提出了一种解决LeetCode 42题"接雨水"的双指针优化解法。通过首先定位数组中的最高柱作为分界点,将问题分解为左右两个独立区域。在左侧区域从左向右遍历时维护左侧最大值,右侧区域从右向左遍历时维护右侧最大值。这种方法避免了传统双指针的复杂条件判断,每个柱子仅遍历一次,实现O(n)时间复杂度和O(1)空间复杂度的最优解。文章详细解析了算法思想、代码实现及复杂度分析,展示了如何利用最高柱的天然分割特性简化问题。
2025-08-16 20:32:52
679
原创 力扣(接雨水)——标准双指针
本文详细解析了LeetCode 42题"接雨水"的双指针解法。通过维护左右双指针和对应的最高边界高度,算法在O(n)时间复杂度和O(1)空间复杂度下解决问题。核心思想是移动当前较低侧的指针,计算储水量或更新边界高度。代码实现中,先处理边界条件,再通过双指针动态比较左右高度,累计可储存的雨水量。这种方法比暴力解法更高效,避免了重复遍历,是解决此类问题的经典优化方案。
2025-08-15 19:37:28
599
原创 力扣(接雨水)——单调栈
本文深度解析了LeetCode 42题"接雨水"的单调栈解法。通过构建单调递增栈,算法能高效识别凹槽并计算储水量:遇到更高柱子时触发凹槽处理,计算左右边界间的储水容量。代码实现中,栈维护柱子下标以保证单调性,出栈时计算凹槽的储水量。该算法实现了O(n)时间复杂度和O(n)空间复杂度,有效解决了暴力解法效率低的问题。文章详细拆解了算法思想、代码执行流程和复杂度分析,展现了单调栈在解决凹槽类问题中的精妙应用。
2025-08-15 19:34:01
834
原创 力扣(盛最多水的容器)
本文解析了LeetCode 11题"盛最多水的容器"的双指针解法。题目要求在给定高度数组中找到两条线段,使得与x轴构成的容器能容纳最多的水。传统的暴力枚举法时间复杂度为O(n²),而双指针算法通过从两端向中间移动指针,每次移动较短边的策略,将时间复杂度优化至O(n)。文章详细讲解了双指针的选择逻辑、移动策略,并提供了Java代码实现,分析了其执行流程和关键逻辑。最终,该算法的时间复杂度为O(n),空间复杂度为O(1),是解决该问题的高效方案。
2025-08-14 18:16:27
699
原创 力扣(串联所有单词的子串)
摘要:本文探讨了串联所有单词的子串问题,提出了一种基于多滑动窗口和哈希表的高效解法。通过将单词固定长度(wordLen)作为关键特征,设计多个滑动窗口(对应不同起始偏移)来覆盖所有可能的子串组合。算法利用哈希表统计目标词频和窗口词频,在滑动过程中动态维护窗口内容,通过移除旧单词和添加新单词来优化匹配效率。代码实现采用预处理和双重循环结构,确保精准匹配所有符合条件的子串起始索引。时间复杂度分析表明,该方法在合理控制计算量的前提下,能够有效处理大规模输入。
2025-08-14 18:12:08
1050
原创 力扣(O(1) 时间插入、删除和获取随机元素)
因为要实现随机获取元素且每个元素概率相同,我们可以利用 Random 类生成随机索引(范围是 0 到 list.size() - 1 ),然后通过 list.get(randomIndex) 快速获取元素,时间复杂度为 O(1)。O(1) 时间插入、删除和获取随机元素这道题,通过巧妙结合哈希表和动态数组,充分发挥了两者的优势,成功实现了插入、删除、随机获取操作平均时间复杂度为 O(1) 的需求。删除元素时,直接删除动态数组中间的元素时间复杂度会是 O(n) (需要移动元素 )。
2025-08-13 19:17:46
1004
原创 力扣(跳跃游戏I/II)
本文解析了LeetCode 55和45两道跳跃游戏题目。55题要求判断能否到达终点,通过贪心算法动态维护能到达的最远位置maxReach,时间复杂度O(n)。45题要求计算最小跳跃次数,同样采用贪心策略,维护currentEnd和farthest边界变量,在必须跳跃时才增加次数,保证跳跃最少,时间复杂度O(n)。两题都体现了贪心算法"局部最优推导全局最优"的思想,55题关注能否覆盖终点,45题则通过边界优化实现最少跳跃。
2025-08-13 19:12:14
1023
原创 力扣(买卖股票的最佳时机I/II)
本文分析了LeetCode股票买卖问题的两道经典题目。121题要求在单次交易中获取最大利润,通过贪心算法维护最低买入价并在遍历时计算最大差价,时间复杂度O(n)。122题允许多次交易,解题思路是累计每次价格上涨的利润总和,同样采用贪心策略实现O(n)时间复杂度。两道题目都体现了贪心算法在局部最优推导全局最优问题中的高效性,为解决类似数组遍历和策略选择问题提供了参考。
2025-08-10 18:10:55
1269
原创 力扣(H指数)
H指数定义为至少有h篇论文被引用h次以上的最大h值。算法采用排序+线性遍历的策略:首先对论文引用次数数组进行升序排序(O(nlogn)时间复杂度),然后从前向后遍历,当发现当前论文的引用次数≥剩余论文数量时,该数量即为H指数。这种贪心策略能高效找出最大H值,整体空间复杂度为O(logn)。以[3,0,6,1,5]为例,排序后为[0,1,3,5,6],当遍历到第三篇(3≥3)时确定H指数为3。
2025-08-10 18:10:44
622
原创 力扣(删除有序数组中的重复项I/II)
本文解析了LeetCode两道有序数组去重问题(26题和80题),重点介绍了双指针的通用解法。对于仅允许元素出现一次的26题,使用快慢指针比对当前元素与唯一区域末尾;允许出现两次的80题则通过比较当前元素与key-2位置的元素来控制重复次数。两题都实现了O(1)空间复杂度处理,26题返回key+1作为新长度,80题直接返回key指针位置。文章通过代码示例和逻辑拆解,展示了如何通过调整指针比较策略来应对不同的重复次数限制要求。
2025-08-09 18:30:39
640
原创 力扣(轮转数组)
本文全面解析了数组轮转问题的两种解法。三次反转法通过整体反转、前k个反转和剩余部分反转三个步骤,实现O(1)空间复杂度的原地修改;额外数组法则利用新数组和位置映射公式(i+k)%n实现轮转,空间复杂度O(n)。两者时间复杂度均为O(n),但三次反转法空间效率更优,适合大规模数据;额外数组法逻辑直观,适合小规模数据或追求可读性的场景。文章还讨论了处理k大于数组长度的优化技巧(取模运算),并比较了两种方法的适用场景,为算法实践提供了灵活选择方案。
2025-08-09 18:30:31
1003
原创 链表超详细讲解(双向链表与循环链表实现)
/删除链表的最后一个节点(忽略尾哨兵)//直接用尾哨兵找到当前的最后一个节点//判断尾哨兵的前驱是否为头哨兵,如果为头哨兵则链表此时为空,抛出异常throw new IllegalArgumentException(String.format("链表为空"));//找到最后一个节点的前驱节点/*--完成删除操作--*///将删除节点的前驱节点的后继修改为尾哨兵//将尾哨兵的前驱修改为删除节点的前驱双向链表:通过prev和next支持双向遍历,适合频繁前后查找的场景。
2025-08-08 14:39:36
880
原创 链表超详细讲解(链表基础概念与哨兵节点)
链表是由节点串联而成的数据结构,每个节点包含两部分:数据域:存储元素值;指针域:指向其他节点(单向链表指向后继,双向链表还指向前驱)。与数组的核心区别:数组:内存连续,可通过索引随机访问,但长度固定,扩容成本高;链表:内存分散,需顺序访问,但长度动态,插入 / 删除效率高(无需移动元素)。哨兵节点,又称哑节点,是一种特殊的节点,在链表等数据结构中广泛应用。哨兵节点本身不存储有实际意义的数据,它是一个额外增设的节点,纯粹为了简化边界条件的处理。比如在单向链表中,它可以位于头节点之前;
2025-08-08 14:38:15
1064
原创 多线程(线程的创建与常见方法的使用)
本文介绍了Java中线程的创建与常用方法。线程有三种创建方式:继承Thread类(简单直接但扩展性差)、实现Runnable接口(扩展性强,可共享资源)和Callable接口结合FutureTask(可获取返回值)。文章还详细讲解了线程的常用方法,包括名称设置、休眠、优先级调整、守护线程设置、线程礼让和插队等操作,帮助开发者更好地控制线程执行流程,实现多线程协作与同步。这些技术能有效提升程序并发处理能力。
2025-08-04 17:01:04
1186
原创 递归算法—阶乘(Java)
递归(Recursion)是一种算法思想,指函数在执行过程中直接或间接调用自身的编程技巧。它将复杂问题分解为与原问题结构相似但规模更小的子问题,通过解决子问题逐步推导出原问题的解。在数学和计算机科学中,递归广泛应用于阶乘计算、斐波那契数列、树遍历、图论等场景。n!n!(其中0!= 1为基础条件)。
2025-07-22 07:20:02
500
原创 链表超详细讲解(单向链表实现)
链表是一种动态数据结构,由节点通过指针链接组成,与数组相比具有内存分配灵活、易于增删节点的特点。主要类型包括单向链表(只能单向遍历)、双向链表(支持双向访问)和循环链表(首尾相连)。哨兵节点作为特殊辅助节点,可简化边界处理,避免空指针异常。Java实现单向链表时,需考虑初始化、插入(头部、尾部、指定位置)和删除(头部、指定节点)操作,注意时间复杂度差异(头部操作为O(1),遍历操作为O(n))。关键点在于正确处理节点间的指针引用关系。
2025-07-12 04:00:46
783
原创 动态数组的实现(Java)
在编程实践中,我们日常学习的静态数组常受限于固定长度的特性,难以应对运行时动态数据操作的场景。例如,当程序需要在执行过程中动态添加元素时,静态数组因预先设定的容量无法扩展,会导致数据存储需求与空间限制的矛盾。此时,动态数组(以 int 类型为例)成为更优解决方案。
2025-07-05 20:08:30
1221
原创 二分查找算法详解
二分算法在有序数组中查找特定元素时,在升序的情况下先定义数组的左边界和右边界,通过计算两者中间的索引,获取中间索引对应的值与目标值进行比较。如果目标值等于中间值则返回索引,如果目标值小于中间值,在左半区继续查找,更新右边界。如果目标值大于中间值,在右半区查找,更新左边界。如此循环,直到找到目标值或确定元素不存在。target为目标元素;nums为有序数组;right为右边界;
2025-06-28 20:10:28
325
原创 Linux中常用的文本编辑器
在Linux环境中,选择合适的文本编辑器对于提高工作效率至关重要。本文将详细介绍七种广泛使用的文本编辑器,包括它们的特点、优势和适用场景,帮助用户根据自己的需求和偏好做出最佳选择。在本文中,我们详细介绍了七种在Linux系统中常用的文本编辑器:Vi/Vim、Nano、GNU Emacs、Gedit、Geany、Sublime Text以及Visual Studio Code (VSCode)。每种编辑器都有其独特的优势和适用场景,满足了从初学者到专业开发者的不同需求。
2024-07-24 21:37:02
7278
原创 MySQL双主同步
MySQL,作为全球最流行的关系型数据库管理系统之一,以其卓越的性能、稳定性和灵活性,被广泛应用于各种规模和类型的业务场景。然而,随着业务复杂度的提升和用户需求的多样化,单一数据库实例已难以满足高可用性、数据一致性和负载均衡的综合需求。在这样的背景下,MySQL双主同步技术应运而生,成为提升数据库系统可用性和性能的关键策略之一。本文旨在深入探讨MySQL双主同步的实现原理、配置步骤和优化技巧,帮助大家更好地理解和掌握这一技术。
2024-07-23 22:18:55
1569
1
原创 Harbor的安装部署
Harbor是一个开源的企业级容器镜像仓库,最初由VMware公司的中国团队开发。它旨在提供安全、高性能和易于管理的容器镜像存储、签名和扫描服务。Harbor扩展了开源Docker Distribution的功能,增加了用户通常需要的安全性、身份和管理功能,使得注册表更加接近构建和运行环境,提高了图像传输效率。Harbor支持在注册表之间复制镜像,并提供高级安全功能,如用户管理、访问控制和活动审核。
2024-07-20 23:07:21
2213
1
原创 Linux中Docker的安装部署
Docker是一个开源的应用容器引擎,它允许开发者打包他们的应用以及依赖环境到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows上,也可以实现虚拟化。Docker容器是完全使用沙箱机制,相互之间不会有任何接口。Docker容器的优势在于快速启动、资源占用少、易于移植和管理,以及能够在隔离的环境中运行应用程序。
2024-07-18 11:40:10
685
1
基于SpringBoot,VUE3,Uni-App的勤工助学管理系统(学生端、教师端、管理端)
2025-08-01
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅