数据结构与算法-力扣解题
文章平均质量分 86
以普通人的思维视角解决力扣算法题
资深web全栈开发
全栈程序员
php/python/golang/rust 主后端
vue/react 次前端
阿里云/aws 运维
微信 13100258291
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Transformer位置编码深度解析:从“失忆症“到Sin/Cos的设计智慧
本文深入解析Transformer模型中位置编码的设计原理。首先指出Attention机制本身无法感知词序,需要通过位置编码引入顺序信息。文章对比了简单编号方案的缺陷,详细分析sin/cos位置编码的优势:值域有界、周期性泛化、平滑连续。特别强调配对使用sin/cos的关键原因——避免周期性碰撞并支持相对位置计算(通过三角恒等式)。最后通过时钟类比和数学公式,阐明这种设计如何满足位置编码的核心要求:唯一性、有界性、泛化性和相对位置感知能力。原创 2025-12-24 13:10:47 · 890 阅读 · 0 评论 -
LeetCode 2054:两个最好的不重叠活动 —— 从暴力到优化的完整思路
摘要:本文解决最多参加2个不重叠活动以获得最大价值的问题。通过分析背包思路的局限性,提出基于区间调度的动态规划解法。核心步骤包括:按结束时间排序活动,使用动态规划计算每个活动的最优解(单独选或与前序不冲突活动组合),并用二分查找快速定位可组合的前序活动。通过前缀最大值优化将时间复杂度降至O(n log n)。关键技巧在于排序策略选择、二分查找边界处理以及前缀最大值数组的应用。原创 2025-12-23 11:10:36 · 583 阅读 · 0 评论 -
0-1 背包问题完全指南:从理解到模板
本文详细解析了0-1背包问题的动态规划解法。核心思路是通过状态转移方程计算不同容量下的最大价值,重点强调了一维DP必须倒序遍历以避免重复选择物品。提供了二维和一维的标准代码模板,并给出打印具体方案的实现方法。最后总结了0-1背包的解题套路:识别问题特征、套用模板(特别注意遍历顺序)、处理变种情况。文章通过示例和代码演示,帮助读者掌握0-1背包的动态规划解法及其关键实现细节。原创 2025-12-23 10:10:32 · 1153 阅读 · 0 评论 -
告别死记硬背:40岁程序员如何深度理解 LIS 算法?(从 $O(n^2)$ 到 $O(n \log n)$)
摘要: 本文以最长递增子序列(LIS)问题为例,探讨中年程序员如何通过“插槽重构”思维掌握算法。核心策略是固定结尾并记录最佳战绩($O(n^2)$),升级为用tails数组管理插槽以优化兼容性($O(n\log n)$)。关键点在于替换旧数字以降低准入门槛,为未来创造可能性,并通过二分查找快速定位替换位置。代码实现简洁,强调屏蔽公式、关注长度而非内容,以及根据递增类型微调二分策略。最终指出算法学习应聚焦决策思想而非细节实现,逻辑直觉才是核心。原创 2025-12-22 09:41:43 · 574 阅读 · 0 评论 -
并查集(Union-Find)套路详解
并查集是一种高效处理不相交集合的数据结构,支持合并(Union)和查找(Find)操作。其核心实现使用父节点数组和秩数组,通过路径压缩和按秩合并优化,使单次操作时间复杂度接近O(1)。典型应用包括连通性判断、动态连通性问题和分组聚类。文章以LeetCode 2092题为例,展示了如何处理带时间维度的并查集问题,强调按时间排序、批量处理同一时间会议以及使用Reset回退机制等技巧。掌握并查集的基本操作和优化技巧能有效解决各类连通性问题。原创 2025-12-19 09:38:24 · 951 阅读 · 0 评论 -
LeetCode 3652: 按策略买卖股票的最佳时机
本文解决了一个关于利润最大化的问题,通过修改策略数组中的连续k个元素来提升总利润。原始方法是暴力枚举所有可能的修改位置,时间复杂度为O(n²)。优化后采用前缀和预处理,将时间复杂度降至O(n)。具体步骤包括:1)计算原始利润;2)预处理价格和策略的前缀和;3)枚举所有可能的修改区间,利用前缀和快速计算修改后的利润差。该方法显著提升了计算效率,适用于大规模数据。原创 2025-12-18 17:24:17 · 615 阅读 · 0 评论 -
LeetCode 3573. 买卖股票的最佳时机 V - 动态规划解法详解
本文解决了一个允许做多和做空交易的股票买卖问题。给定股票价格数组和交易次数限制k,通过三维动态规划(DP)来追踪空仓、做多持有和做空持有三种状态的最大收益。状态转移方程考虑了交易完成时机,初始化时对所有j都设置持有状态以简化边界处理。最终答案为最后一天完成k笔交易且空仓时的最大收益。算法时间复杂度O(n×k),空间复杂度可优化至O(k)。关键点在于区分两种交易类型,正确处理交易计数和状态转移。原创 2025-12-17 22:15:15 · 873 阅读 · 0 评论 -
LeetCode 3562: 折扣价交易股票的最大利润 - 树形DP+背包问题详解
定义dfs(u)dp0 []int // dp0[b]: 父节点不购买时,预算b的最大收益dp1 []int // dp1[b]: 父节点购买(当前节点可享半价)时,预算b的最大收益size int // 子树最大可能开销(用于剪枝)dp0[b]:父节点没买,当前子树在预算 b 下的最大收益dp1[b]:父节点买了(当前节点可半价),预算 b 下的最大收益size:子树所有节点原价之和(用于背包剪枝)一次 DFS 计算所有预算 [0, budget] 的结果,避免重复计算。树形结构→ 树形DP。原创 2025-12-16 12:51:51 · 924 阅读 · 0 评论 -
LeetCode 3583: 统计特殊三元组 - 从 O(n³) 到 O(n) 的顿悟之旅
摘要 本文探讨了一种高效计算满足特定条件的三元组数量的算法。原始暴力解法时间复杂度为O(n³),通过固定中间元素并动态维护左右频率表,优化至O(n)。关键步骤包括:1) 将问题转化为查找中间元素左右两侧的目标值;2) 使用哈希表快速查询频率;3) 滑动窗口动态更新频率表。算法避免了重复计算,同时注意了大数取模问题。以示例验证了方法的正确性,最终实现了从O(n³)到O(n)的时间复杂度优化。原创 2025-12-09 10:00:29 · 297 阅读 · 0 评论 -
LeetCode 3432. 统计元素和差值为偶数的分区方案数
文章摘要 LeetCode 3432题要求统计将数组分割成两部分后,两部分和差为偶数的方案数。通过前缀和分析发现,差值的奇偶性完全取决于数组总和的奇偶性。若总和为奇数,则无解;若为偶数,则所有n-1种分割方案都满足条件。因此算法只需计算总和,时间复杂度O(n),空间复杂度O(1)。核心发现是差值的奇偶性由总和决定,与具体分割位置无关。原创 2025-12-05 10:09:51 · 194 阅读 · 0 评论 -
LeetCode 3625. 统计梯形的数目 II
本文介绍了如何计算给定点集中能组成梯形的四点组合数量。关键思路是: 找出所有两点线段,按斜率分组 对每组平行线段计算可能配对(C(k,2)) 排除共线、共端点等无效情况(使用容斥原理) 减去平行四边形重复计数(利用中点重合特性) 最终通过斜率分组统计和几何特性判断,高效计算出梯形数量。时间复杂度约为O(n²),适用于中等规模点集。原创 2025-12-03 10:24:47 · 475 阅读 · 0 评论 -
LeetCode 3623. 统计梯形的数目 I
题目要求统计从给定点集中选择四个点组成水平梯形的数量。水平梯形需满足至少一对边平行于x轴。解题关键在于按y坐标分组,计算每组内点的组合数,然后累加不同组之间的组合数。时间复杂度O(n),空间复杂度O(m),其中n为点数,m为不同y值数量。需注意整数溢出和及时取模。代码实现中,先统计各y值的点数,计算每组的边对数,再用累加技巧优化组合计算。示例验证了算法的正确性。该问题本质是组合计数,适用于类似图形计数场景。原创 2025-12-02 20:40:24 · 572 阅读 · 0 评论 -
[特殊字符] LeetCode 2141:如何让 N 台电脑续航最久?——“二分答案“套路一文讲透
本文通过LeetCode 2141题讲解"二分答案"算法,解决多台电脑共享电池的最长运行时间问题。核心思路是将问题转化为判定函数:给定时间t,检查所有电池贡献之和是否满足nt要求。利用二分法在[0, sum(batteries)/n]区间内搜索最大可行t值,保证单调性。文章提供了完整的Go实现,包括64位整型处理以避免溢出,并给出示例测试用例。该算法时间复杂度为O(mlogS),适用于类似求极值的优化问题,体现了二分答案在解决"最大可行值"问题中的高效性。原创 2025-12-01 23:00:25 · 623 阅读 · 0 评论 -
LeetCode 1590:使数组和能被 p 整除(前缀和 + 哈希表优化)
本文讲解LeetCode 1590题「使数组和能被p整除」的解题方法。该题要求移除最短子数组使剩余元素和能被p整除,考察前缀和、哈希表和模运算的应用。核心思路是利用前缀和余数配合哈希表,将O(n²)的暴力枚举优化为O(n)时间复杂度。具体实现时需要注意取模运算的负数处理、哈希表更新顺序以及边界条件判断(如不能移除全部元素)。文章提供了Go语言实现代码,并分析了时间复杂度和常见陷阱,最后给出相关扩展练习题。该解法适用于子数组和模运算相关问题,是前缀和优化的典型应用。原创 2025-11-30 18:28:57 · 1446 阅读 · 0 评论 -
DFS套路详解
本文系统梳理了树形DFS的三大核心套路(自顶向下、自底向上、树形DP),并以LeetCode 2872题为例详细讲解解题思路。文章指出该题采用自底向上DFS收集子树信息,配合贪心策略(当子树和能被k整除时立即切断)可获得最优解。通过分析解题步骤、复杂度及实现细节,总结出树形DFS的本质是信息在树上的传递和聚合,并提供了做题checklist和扩展练习题。掌握这些套路可有效解决大多数树形问题。原创 2025-11-28 09:45:30 · 433 阅读 · 0 评论 -
动态规划解题套路详解 - 以 LeetCode 2435 为例
本文介绍了动态规划(DP)问题的通用解题套路,并通过LeetCode 2435题进行实战演示。DP问题通常具有计数、最值或存在性特征,并满足最优子结构、重叠子问题和无后效性。解题分为四步:1)定义状态(如坐标和余数);2)确定选择(移动方向);3)明确基础情况(起点初始化);4)建立状态转移方程。以矩阵路径问题为例,使用三维数组记录不同余数状态下的路径数,最终计算到达终点且余数为0的路径数量。该方法的时间复杂度和空间复杂度均为O(mnk)。掌握这套"状态-选择-基础-转移"的思考框架,能原创 2025-11-26 09:16:49 · 900 阅读 · 0 评论 -
LeetCode 1015. 可被 K 整除的最小整数 - 数学推导与鸽巢原理
摘要:这道题目要求找到由数字1组成的最小整数N(如1,11,111...),使其能被K整除。通过数学分析发现,当K能被2或5整除时无解。对于其他情况,利用同余运算和鸽巢原理,最多只需循环K次即可确定是否存在解。算法首先排除K为2或5倍数的情况,然后通过维护余数来避免大数计算,在O(K)时间复杂度和O(1)空间复杂度内解决问题。原创 2025-11-25 09:15:23 · 349 阅读 · 0 评论 -
算法中的二进制操作技巧汇总
本文介绍了10种实用的二进制操作技巧,包括判断奇偶性、快速乘除运算、清除/获取最低位1、数值交换、绝对值计算、判断2的幂、统计1的个数以及位掩码应用。这些技巧利用位运算的高效特性,能够显著提升算法和编程竞赛中的代码性能。每个技巧都配有原理解释和Go语言实现示例,涵盖从基础运算到位掩码等高级应用场景。掌握这些技巧有助于编写更简洁高效的代码,特别适合处理二进制相关问题和性能优化场景。原创 2025-11-24 08:53:11 · 369 阅读 · 0 评论 -
LeetCode 1262. 可被三整除的最大和 - 解题思路与代码
本文介绍了解决LeetCode 1262题“可被三整除的最大和”的两种方法。题目要求从数组中选出元素,使其和最大且能被3整除。第一种是贪心算法:先计算总和,若总和模3不为0,则减去最小的一组余1或余2的数。时间复杂度O(NlogN)。第二种是动态规划:维护dp[0-2]表示不同余数的最大和,通过状态转移更新。时间复杂度O(N)。两种方法都能有效解决问题,贪心思路直观,DP效率更高。示例分析验证了算法的正确性。原创 2025-11-23 10:11:13 · 1141 阅读 · 0 评论 -
LeetCode 1930: 长度为 3 的不同回文子序列 - 解题思路与代码实现
本文介绍了LeetCode第1930题"长度为3的不同回文子序列"的解题思路。题目要求统计字符串中长度为3的不同回文子序列数量。作者首先解释了回文子序列的概念,然后从暴力解法(O(n^2))逐步优化到高效解法(O(n))。核心思路是:长度为3的回文子序列必为x y x形式,因此遍历26个字母,对每个字母x找到其最左和最右位置,统计中间不同字符y的数量即可。文章提供了Go语言实现代码,并分析了时间空间复杂度。这种解法通过观察回文结构特征,避免了暴力搜索,适合处理长字符串。原创 2025-11-21 21:55:20 · 744 阅读 · 0 评论 -
力扣2536子矩阵元素加1-差分数组解法详解
本文介绍了使用差分数组技术高效处理矩阵区间更新问题的方法。当需要对二维矩阵进行多次子矩阵元素加1操作时,暴力解法时间复杂度高达O(n²),无法应对大规模数据。通过构造二维差分数组,只需在四个关键位置进行标记操作(O(1)时间复杂度),再通过二维前缀和还原最终矩阵,可将总时间复杂度优化至O(n² + q)。文章详细分析了一维和二维差分数组的原理,解释了四个标记位置的数学依据(容斥原理),并通过具体示例演示操作过程,最后给出了完整的Go语言实现代码。这种方法特别适用于需要大量矩阵区间更新操作的场景。原创 2025-11-14 11:31:26 · 348 阅读 · 0 评论 -
贪心算法套路解析
本文介绍了贪心算法的识别特征和应用方法。贪心算法通常具有最优子结构、贪心选择性质、无后效性和交换论证等特点。文章提供了贪心算法的通用模板,包括状态初始化、最优选择、贡献计算和状态更新等步骤,并列举了区间调度、背包问题等常见套路。通过3228题实例分析,具体说明如何识别贪心特征、设计状态变量、确定最优选择策略,并验证贪心解的正确性。贪心算法的关键在于找到局部最优的"贪心点",通过简单规则实现全局最优解。原创 2025-11-13 10:45:13 · 320 阅读 · 0 评论 -
LeetCode 2654. 使数组所有元素变成 1 的最少操作次数 - GCD 思维题详解
这道题的核心是理解 GCD 的性质和传播规律。它不是传统的算法题,更像是一道数学思维题。理解 1 在 GCD 运算中的特殊地位认识到 GCD 的传播特性通过找最短子数组来优化操作次数通过这道题,我们可以看到算法题有时更需要数学思维,而不是死板的算法模板。原创 2025-11-12 14:08:48 · 1054 阅读 · 0 评论 -
二分搜索中 `right = mid` 而非 `right = mid + 1` 的解释
这涉及到二分搜索的区间定义方式。上述代码使用的是左闭右开区间。区间类型更新方式搜索范围优点缺点闭区间直观易懂需要处理特殊情况半开区间边界清晰,不易出错需要理解右开概念使用而不是语义精确:正好排除已检查的mid位置边界安全:减少数组越界和逻辑错误风险标准做法:符合计算机科学中的常见模式性能相同:两种写法的时间复杂度都是 O(log n)区间一致性:与左闭右开区间的定义保持一致这种写法体现了左闭右开区间。原创 2025-11-11 23:02:33 · 888 阅读 · 0 评论 -
告别死记硬背!一文彻底搞懂单调栈的本质与应用
单调栈是一种特殊的栈结构,栈内元素保持单调性(递增或递减)。但这只是表象!单调栈的本质是用栈动态维护"全局待定"元素集合,通过弹出操作完成"全局问题→局部确定"的转化过程。不是机械的"维护单调性"而是动态的"全局→局部转化"栈只是载体,转化才是本质。原创 2025-11-11 08:00:00 · 900 阅读 · 0 评论 -
最大化最小值 / 最小化最大值 - 算法套路总结
摘要 二分法是解决"最大化最小值"和"最小化最大值"类问题的有效方法。其核心思想是将原问题转换为"判断某个值是否可行",利用单调性进行二分搜索。解题分为四步:1)识别问题类型;2)确定搜索范围;3)设计检查可行性的check函数;4)实现二分主循环。典型案例包括木材切割和任务分配问题。该方法通过将复杂问题简化为可行性验证,显著降低了计算复杂度,时间复杂度通常为O(n log M),其中n是数据规模,M是可能答案范围。 (148字)原创 2025-11-08 09:00:00 · 1785 阅读 · 0 评论
分享