算法训练营
文章平均质量分 61
代码随想录算法训练营
Unstoppable22
技术侠客
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
代码随想录算法训练营第 61 天 | Floyd 算法精讲、A* 算法精讲(A star 算法)
DFSBFSPrim:稠密图,时间复杂度为 O(V^2)。Kruskal:稀疏图,时间复杂度为 O(E * logE)。BFS:无向图且权值都为 1,相当于无权图。Dijstra:有向图、单源、权值正数。朴素法:稠密图,时间复杂度为 O(V^2)。堆优化法:稀疏图,时间复杂度为 O(E * logE)。Bellman_ford:有向图、单源点、权值可以为负数 或者 检测负权环路 或者有限节点最短路径。普通:稠密图,时间复杂度为 O(V * E)。原创 2025-12-09 19:38:34 · 877 阅读 · 0 评论 -
代码随想录算法训练营第 60 天 | Bellman_ford 队列优化算法(又名 SPFA)、Bellman_ford 之判断负权回路、Bellman_ford 之单源有限最短路
Dijkstra 更像是贪心算法;Bellman_ford 更像是动态规划算法,所以能找负权值的和限制途经节点个数的。Dijkstra 和 Bellman_ford 的队列优化算法有点像。前者是找最小距离的节点,后者是找相连并更新的节点。前者没有用到队列,后者用到队列。二者都是找到节点后就更新节点到源点的距离。二者都要设置 minDist 数组,并把 minDist[start] = 0。原创 2025-12-08 15:21:58 · 656 阅读 · 0 评论 -
代码随想录算法训练营第 58 天 | Dijkstra(堆优化版)精讲、Bellman_ford 算法精讲
对所有边松弛 n - 1 次。(因为源点通过 n - 1 条边肯定可以到达终点。对题目给出的 n 条边依次松弛,总共松弛 n - 1 轮。松弛 n - 1 次:将所有点到源点的最短距离都更新完毕。松弛一次:从源点出发,与源点一条边相连的节点的最短距离。松弛两次:从源点出发,与源点两条边相连的节点的最短距离。可以解决带负权值的问题。但是不能出现负权值环路。重点:minDist[1] 要初始化为 0。堆优化版时间复杂度:O(E * logE)朴素版时间复杂度:O(V^2)时间复杂度:O(V * E)原创 2025-12-06 14:07:20 · 316 阅读 · 0 评论 -
代码随想录算法训练营第 57 天 | 拓扑排序精讲、Dijkstra(朴素版)精讲
不用在重新遍历一遍 inDegree 数组,不然还得区分哪些入度为 0 的节点之前已经放到队列中了。不仅是求源点到终点的最短距离,而且它把源点到所有节点的最短距离都求出来了。用一维数组 int[] parent。指向为 parent[i] -> i。一个是从最小生成树出发,一个是从源点出发。结果集个数小于 n,成环,输出 -1。注意本题节点从 0 到 n - 1。邻接表,这样不用判 null。注意本体节点从 1 到 n。拓展:输出最短路径的每条边。原创 2025-12-05 17:06:02 · 583 阅读 · 0 评论 -
代码随想录算法训练营第 56 天 | 53. 寻宝(Prim + Kruskal)
可以用 HashMap 或一维数组 int[] parent。不能用一维数组 int[] parent,因为可能会出现如下情况:1 同时连 2 和 3,会被覆盖。由于 Kruskal 算法直接是针对边进行遍历的。这里直接用 List<int[]> 来保存边。遍历 n - 1 次,因为每次循环找到了一条边,只要找到 n - 1 条边即可。不能用 List<int[]>,因为会添加很多次,需要覆盖之前的添加。节点从 1 到 n。拓展:输出最小生成树的每条边。拓展:输出最小生成树的每条边。适合稠密图,点少边多。原创 2025-12-04 16:20:29 · 383 阅读 · 0 评论 -
代码随想录算法训练营第 55 天 | 108. 冗余连接、109. 冗余连接II
每添加一条边,就判断这两个节点是否在统一集合。如果是,说明它是冗余的最后一条边,立即返回;否则把这两个节点添加到一个集合中。拓展:树是一种无向无环图,n 个节点只需要 n - 1 条边就能完全联通。只有 1 条冗余边。原创 2025-12-03 14:56:44 · 299 阅读 · 0 评论 -
代码随想录算法训练营第 54 天 | 并查集理论基础、107. 寻找存在的路径
可用 dfs 或 bfs,这里用并查集。原创 2025-12-02 13:39:03 · 239 阅读 · 0 评论 -
代码随想录算法训练营第 53 天 | 106. 岛屿的周长、110. 字符串接龙、105. 有向图的完全联通
无权图求最短路径,不需要迪杰特斯拉算法,只需要 dfs 或 bfs 即可。抽象图用 graph,二维图用 grid。邻接矩阵用graph[][],邻接表用。// 节点数量// 边数量// 节点数量// 边数量i < n + 1;i++) { // i 必须从 0 开始,创建 n + 1 个空列表。原创 2025-12-01 16:54:54 · 713 阅读 · 0 评论 -
代码随想录算法训练营第 51 天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 高山流水、104. 建造最大岛屿
遍历第一行、最后一行、第一列、最后一列。遇到陆地就将它相邻的所有陆地都标记为 0(省去 visited 数组)。最后统计 grid 有多少个 1。被标记为 true 的节点不会再次访问。必须先把 1 变为 0,再把 2 变为 1,否则会覆盖导致数组全为 0。暴力方法:每个海洋都尝试变成陆地,然后统计最大岛屿面积。代码以 dfs 为例:dfs 很简单,主函数有点复杂。暴力时间复杂度:O(n * m * n * m)注意:题目要求的是孤岛总面积而不是孤岛个数。时间复杂度:O(n * m * n * m)原创 2025-11-30 23:40:14 · 1065 阅读 · 0 评论 -
代码随想录算法训练营第 50 天 | 99. 岛屿数量、100. 岛屿的最大面积
遍历每个地方,如果该处为陆地,且未访问过。将结果加 1.并将该处所连的陆地全部标记为已访问。dfs ——先格子赋值为 true,再进入 dfs 函数。(dfs 隐式终止条件)dfs ——判断完终止条件后,再赋值为 true。(dfs 显式终止条件)重点:队列刚一放进去元素,visited 数组就要立马标记为 true。dfs 或 bfs 时,可以只搜右下的格子。原创 2025-11-28 23:51:58 · 687 阅读 · 0 评论 -
代码随想录算法训练营第 49 天 | 98. 可达路径 / 797. 所有可能的路径
注意:有向无环图不需要 visited 数组。需要提前在 path 中把节点 1 加上。,在 Java 中为锯齿数组。(因为节点从 1 到 n)LeetCode 模式。原创 2025-11-28 00:07:54 · 233 阅读 · 0 评论 -
代码随想录算法训练营第 48 天 | 42. 接雨水、84. 柱状图中最大的矩形
创建两个数组,分别表示当前柱子左边最高柱子(包括自身)的高度和右边最高柱子(包括自身)的高度。根据木桶效应,某个位置能装的水的高度为左边最高柱子高度和右边最高柱子高度的最小值。但是知道它右边某个柱子的右边最高柱子高度是大于上面已经求出来的左边最高柱子的高度。左边最高柱子高度 = 它左边柱子的左边最高柱子的高度和它本身高度,取最大值。高度为右边更高的柱子和左边更高的柱子的最小值,还要减去当前柱子的高度!某个位置,已经知道它左边最高柱子的高度,它右边最高柱子的高度还没求。空间复杂度:O(n)原创 2025-11-26 22:00:21 · 1467 阅读 · 0 评论 -
代码随想录算法训练营第 47 天 | 739. 每日温度、496. 下一个更大元素 I、503. 下一个更大元素 II
单调栈的核心是放索引,而不是具体的值。(因为直到索引可以去数组中找对应的值;而知道值不能得到索引,且值可能重复。如果是求右边第一个大的:从栈顶到栈底递增如果是求右边第一个小的:从栈顶到栈底递减单调栈其实有正序遍历和倒序遍历,暂时只掌握正序遍历就可以了。单调栈模板while 循环要判断栈非空while 结束后不要忘记 pushi < n;stack.isEmpty() && nums[i] > nums[stack.peek()]) { // 必须判断栈非空。原创 2025-11-25 23:04:13 · 451 阅读 · 0 评论 -
代码随想录算法训练营第 46 天 | 647. 回文子串、516. 最长回文子序列
因为只需对矩阵右上三角便利,所以从左上到右下的对角线需初始化。:[i, j] 字符串的最长回文子序列长度。:[i, j](左闭右闭)的字符串是不是回文子串。遍历顺序:从下到上,从左到右(假设 j >= i)(因为根据递推公式,是从左下角往右上角推导的。初始化:全部初始化为 false。上题的子串:要求必须连续。前两种情况可以合并。子序列:可以不连续。从下到上,从左到右。原创 2025-11-24 20:59:01 · 191 阅读 · 0 评论 -
代码随想录算法训练营第 44 天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离
评论区笔记评论区笔记2一般如果要是求的子数组是连续的,或者即使不是连续的,要求单调这种,都是需要定义 dp 是以 nums[i] 为结尾,最终结果是 max(dp)。因为如果不定义是以 nums[i] 为结尾,那么这时候即使做 nums[i] 的比较,也无法更新 dp[i],因为不知道 dp[i-1] 是不是以 nums[i-1] 结尾,如果不是,题目要求的数组的连续的,那就没法 dp[i] = dp[i-1]+1。原创 2025-11-22 23:58:17 · 859 阅读 · 0 评论 -
代码随想录算法训练营第 43 天 | 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和、392. 判断子序列
考虑 i - 1、j - 1 的最长公共子序列的长度。(注意:不一定选,和。两个指针 p1、p2。如果字符相等就都右移一位;如果不相等就 p2 右移一位。如果 p1 先到末尾,返回 true;如果 p2 先到末尾,返回 false。值得学习——循环条件与运算的利用(不需要判断字符串为空的特殊情况),再判断最长公共子序列长度等不等于 s 的长度。(基于 i -1、j - 1 不一定选的基础):以 i 结尾的最大数组和。两个方法本质上一致。原创 2025-11-21 23:28:26 · 391 阅读 · 0 评论 -
代码随想录算法训练营第 42 天 | 300. 最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组
可以避免初始化时(dp[0][j]、dp[i][0]),初始第一行和第一列。一个小优化:把 result 更新放在 for 循环里面,使得代码更简洁。:以 i - 1、j - 1 为结尾的最长重复子数组。:以 nums[i] 结尾的最长连续子序列的长度。初始化:全赋为 1,因为最小长度就是 1。原创 2025-11-20 19:26:31 · 253 阅读 · 0 评论 -
代码随想录算法训练营第 41 天 | 188. 买卖股票的最佳时机 IV、309. 买卖股票的最佳时机含冷冻期、714. 买卖股票的最佳时机含手续费
除了 0 之外,2 * k 个状态。奇数为持有(买入),偶数为不持有(卖出)。卖出时减去手续费即可。原创 2025-11-19 22:33:59 · 408 阅读 · 0 评论 -
代码随想录算法训练营第 40 天 | 121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II、123. 买卖股票的最佳时机 III
第 i 天持有股票的现金:前一天持有股票和当天买入的最大值。当天买入:前一天未持有股票的现金减当天买入的现金(因为可以买卖多次,前一天的初始现金未必是 0)第 i 天不持有股票的现金 = 前一天不持有和当天卖出的最大值。第 i 天持有股票的现金 = 前一天持有和当天买入的最大值。:第 i 天未持有(包括未买入和已经卖出)股票的收益。当天卖出:当天卖出的现金加上前一天未持有的负现金。:第 i 天第 1 次未持有股票。:第 i 天第 2 次未持有股票。:第 i 天第 1 次持有股票。:第 i 天未操作。原创 2025-11-18 21:44:21 · 410 阅读 · 0 评论 -
代码随想录算法训练营第 39 天 | 198. 打家劫舍、213. 打家劫舍 II、337. 打家劫舍 III
注意到情况二包含情况一的情况;情况三也包含情况一的情况。所以只有 2 种情况,取最大值即可。dp[i]:考虑第 i 间屋子能获得的最大价值。(注意只是考虑,不代表就一定选。为了解决首尾不能同时取的情况,将原情况分为 3 个子情况。每个节点有一个二维数组 dp。树形 dp + 后序遍历。原创 2025-11-17 22:37:52 · 311 阅读 · 0 评论 -
代码随想录算法训练营第 37 天 | 322. 零钱兑换、279. 完全平方数、139. 单词拆分、多重背包
dict = {“apple”, “pen”},apple为 1,pen 为 2。这样就 for 循环中就不需要 if 判断了。小优化:为 true 后直接 break。初始化:dp[0] = 0,其他为。必须是排列顺序 121,不能是112。因为递推公式取的是 min。是排列问题,不是组合问题!先遍历背包,再遍历物品。原创 2025-11-16 20:14:54 · 643 阅读 · 0 评论 -
代码随想录算法训练营第 36 天 | 完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ、爬楼梯(进阶版)
这个区别也导致了 01 背包和完全背包。初始化时比较巧妙的是将。,同时也运用递推公式。原创 2025-11-14 23:42:46 · 446 阅读 · 0 评论 -
代码随想录算法训练营第 35 天 | 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
题目链接类似于416. 分割等和子集,尽量分出两堆重量相近的石头。sum += x;i < n;i++) {j--) {01 背包1.1 二维数组dp[i][j]0~i的物品任意放入容量为j的背包,最大的价值。初始化:第一列dp[i][0]初始化为 0,第一行dp[0][j]从第一个满足 0 号物品的地方开始初始化为不为 0。(按需初始化)遍历顺序:遍历顺序可以颠倒。for循环中,i从1开始遍历;j从0或1皆可。1.2 一维数组dp[j]:容量为j的背包的最大价值。原创 2025-11-13 17:05:38 · 706 阅读 · 0 评论 -
代码随想录算法训练营第 34 天 | 01 背包理论基础 - 二维数组、01 背包理论基础 - 一维数组、416. 分割等和子集
对于 01 背包二维 dp 数组的实现,其遍历顺序可以颠倒。原创 2025-11-12 23:16:31 · 493 阅读 · 0 评论 -
代码随想录算法训练营第 33 天 | 62. 不同路径、63. 不同路径 II、343. 整数拆分、96. 不同的二叉搜索树
状态压缩,一维数组:新 = 旧(新上)+ 旧左。dp[i] 表示 i 的最大乘积。优化:for 循环中,原创 2025-11-12 00:19:54 · 428 阅读 · 0 评论 -
代码随想录算法训练营第 32 天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
dp 数组以及下标的含义递推公式dp 数组如何初始化遍历顺序打印 dp 数组(出错时使用)i <= n;i++) { // k 为实际的第几个数。如 k = 2 表示计算第 2 个数的值p = q;q = sum;return sum;或i <= n;i++) { // k 为实际的第几个数。如 k = 2 表示计算第 2 个数的值p = q;q = sum;return sum;原创 2025-11-10 21:17:32 · 382 阅读 · 0 评论 -
代码随想录算法训练营第 30 天 | 56. 合并区间、738. 单调递增的数字、968. 监控二叉树
其实一共有 6 种常规情况(2C3 + 3 = 6),上面第一种情况包含 1 种,第二种情况包含 3 种,第三种情况包含 2 种。,而是用 result 数组的最后一个元素的右边界。赋成 9(防止 1000 -> 0900 的情况,应该是 1000 -> 999)从后向前遍历,遇到前一位大于后一位,前一位减 1,后一位及之后全部赋成 9.对 null 节点,应该设置为有覆盖状态。优先从叶子节点往上遍历,在叶子节点的父节点放摄像头。0 -> 无覆盖(未被摄像头覆盖)2 -> 有覆盖(被摄像头覆盖)原创 2025-11-08 17:32:23 · 628 阅读 · 0 评论 -
代码随想录算法训练营第 29 天 | 452. 用最少数量的箭引爆气球、435. 无重叠区间、763. 划分字母区间
记录每个元素最后出现的位置。从左往右遍历,遇到更远的位置就更新,当遍历到最远位置时,就划分出了一个区间。在判断有没有第三个或更多气球重叠时,更新右边界(取最小的右边界)注意:右边界和左边界相等(相邻)也能一次射爆。原创 2025-11-07 21:17:54 · 509 阅读 · 0 评论 -
代码随想录算法训练营第 28 天 | 134. 加油站、135. 分发糖果、860. 柠檬水找零、406. 根据身高重建队列
本文总结了几道典型贪心算法题目的解题思路: 加油站问题:通过维护当前油量和总油量,确定能否完成环线行驶,并找到合适的出发站点。 分发糖果:采用两次遍历,先满足右规则再满足左规则,确保相邻高分儿童获得更多糖果。 柠檬水找零:优先使用大额零钱进行找零的策略,保证找零过程最优。 身高重建队列:先按身高降序排序,再根据排名插入,确保矮个子插入不影响高个子的排名。 这些题目展现了贪心算法的核心思想:通过局部最优选择达到全局最优解,特别是处理多维度问题时,采用分步处理策略能有效简化问题复杂度。原创 2025-11-06 23:14:57 · 433 阅读 · 0 评论 -
代码随想录算法训练营第 27 天 | 122. 买卖股票的最佳时机 II(妙)、55. 跳跃游戏、45. 跳跃游戏 II、1005. K 次取反后最大化的数组和
不去看细节(具体跳几步),只看覆盖范围,能不能盖住终点。排序,更方便取最小正数(即最后一个元素)。每次要最大的覆盖范围,直到覆盖终点.差分,只有利润为正才买入。原创 2025-11-05 15:40:02 · 147 阅读 · 0 评论 -
代码随想录算法训练营第 26 天 | 455. 分发饼干、376. 摆动序列、53. 最大子数组和
当出现平坡时,要么删除左边的,要么删除右边的,假设我们删除左边的。当连续和为负数时,与其拖累后面的数,不如从新出发。1 - 1 的摆动序列长度是 1。1 - 2 的摆动序列长度是 2。只有在坡度方向改变时,才设置。先遍历胃口,再遍历饼干。先遍历饼干,再遍历胃口。对于首尾元素怎么特殊处理。可以增加一个虚拟头节点。默认一开始坡度为 1。原创 2025-11-04 15:13:12 · 187 阅读 · 0 评论 -
代码随想录算法训练营第 25 天 | 491. 非递减子序列、46. 全排列、47. 全排列 II、51. N 皇后、37. 解数独
所有的回溯都是深搜所有的深搜都是递归子集问题可以不用写 终止条件,因为 for 循环不满足会自动返回。子集问题上来就收获结果。如果数组允许排序,可以用,见组合总和 II如果数组不允许排序,每层递归设置一个usedSet,用,见非递减子序列当要收集全部结果时,用 void当只要收集到一个满足条件的结果就返回时,用 boolean,如解数独类似于二叉树的路径总和 1 和路径总和 2。原创 2025-11-03 16:22:08 · 813 阅读 · 0 评论 -
代码随想录算法训练营第 23 天 | 93. 复原 IP 地址、78. 子集、90. 子集 II
需要额外验证最后一段,最后一段再返回条件成立时验证。不用 path,直接在字符串上加句点。收获结果,而不是只在叶子节点。前面的段在单层逻辑中验证。子集问题比较特殊:要去。原创 2025-11-02 21:57:06 · 307 阅读 · 0 评论 -
代码随想录算法训练营第 22 天 | 39. 组合总和、40. 组合总和 II、131. 分割回文串
三部曲函数参数返回值确定终止条件单层搜索逻辑for 循环内部递归时,如果不能重复选自己,就是;如果可以,就是。原创 2025-11-01 22:07:53 · 722 阅读 · 0 评论 -
代码随想录算法训练营第 21 天 | 77. 组合、216. 组合总和 III、17. 电话号码的字母组合
包含 5 类问题组合切割子集排列棋盘void backtracking(参数) {if (终止条件) {收集结果;return;for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;递归函数;回溯操作;return;可以抽象成一棵树。注:组合、切割、排列和部分棋盘问题都是在叶子节点收集结果。只有子集问题是在每个节点收集结果。原创 2025-10-31 00:26:56 · 717 阅读 · 0 评论 -
代码随想录算法训练营第 20 天 | 669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树
【代码】代码随想录算法训练营第 20 天 | 669. 修剪二叉搜索树。原创 2025-10-28 23:45:32 · 234 阅读 · 0 评论 -
代码随想录算法训练营第 19 天 | 235. 二叉搜索树的最近公共祖先、701. 二叉搜索树中的插入操作、450. 删除二叉搜索树中的节点
二叉搜索树的题目,一般用迭代法比较简单。(且由于 BST 的有序性,迭代方法不需要用到栈)原创 2025-10-28 23:45:13 · 438 阅读 · 0 评论 -
代码随想录算法训练营第 18 天 | 530. 二叉搜索树的最小绝对差、501. 二叉搜索树中的众数、236. 二叉树的最近公共祖先
如果是第二种情况,自己是最近公共祖先,那么遇到自己的时候就直接返回了,甚至不会遍历自己下面的节点。型,设置成节点的值的实际类型以避免判断空指针(大部分为。简单方法:中序遍历转成数组,判断数组相邻元素差最小值。左子树判断为空,右子树判断不为空,返回右子树。左子树判断不为空,右子树判断为空,返回左子树。左子树和右子树判断都不为空,返回这个节点。如果都为是,则该节点为最近公共祖先。是中序遍历,所以能够满足题意。左右子树判断都为空,返回空。,再遍历过程中得出最小值。要从下往上返回逻辑,用。原创 2025-10-27 21:05:53 · 674 阅读 · 0 评论 -
代码随想录算法训练营第 16 天 | 654. 最大二叉树、617. 合并二叉树、700. 二叉搜索树中的搜索、98. 验证二叉搜索树
构造二叉树的题目,一定用前序遍历:中左右。原创 2025-10-25 23:26:31 · 303 阅读 · 0 评论 -
代码随想录算法训练营第 15 天 | 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树、105. 从前序与中序遍历序列构造二叉树
递归函数什么时候需要返回值?什么时候不需要返回值?原创 2025-10-24 15:53:52 · 1681 阅读 · 0 评论
分享