- 博客(53)
- 收藏
- 关注
原创 代码随想录算法训练营第六十二天|图论专题:Floyd 算法、A * 算法
本题是经典的多源最短路问题。在这之前我们讲解过,dijkstra朴素版、dijkstra堆优化、Bellman算法、Bellman队列优化(SPFA) 都是单源最短路,即只能有一个起点。而本题是多源最短路,即 求多个起点到多个终点的多条最短路径。通过本题,我们来系统讲解一个新的最短路算法-Floyd 算法。。Floyd算法核心思想是动态规划。例如我们再求节点1 到 节点9 的最短距离,用二维数组来表示即:grid[1][9],如果最短距离是10 ,那就是 grid[1][9] = 10。
2025-04-14 10:15:12
810
原创 代码随想录算法训练营第六十天|图论专题:Bellman_ford 队列优化算法、bellman_ford之判断负权回路、bellman_ford之单源有限最短路
初始化dist[]为 ∞,源点设为 0。执行 V-1 次“松弛操作”。再做一次第 V 次松弛操作若还有更新 → 存在负权环!
2025-04-13 16:48:44
976
原创 代码随想录算法训练营第五十九天|图论专题:dijkstra(堆优化版)、Bellman_ford 算法
这里要给大家模拟一遍 Bellman_ford 的算法才行,接下来我们来看看对所有边松弛 n - 1 次的操作是什么样的。我们依然使用。
2025-04-11 11:43:11
960
原创 代码随想录算法训练营第五十八天|图论专题:拓扑排序、dijkstra(朴素版)
其实拓扑排序是经典的图论问题。先说说 拓扑排序的应用场景。大学排课,例如 先上A课,才能上B课,上了B课才能上C课,上了A课才能上D课,等等一系列这样的依赖顺序。问给规划出一条 完整的上课顺序。拓扑排序在文件处理上也有应用,我们在做项目安装文件包的时候,经常发现 复杂的文件依赖关系, A依赖B,B依赖C,B依赖D,C依赖E 等等。如果给出一条线性的依赖顺序来下载这些文件呢?有录友想上面的例子都很简单啊,我一眼能给排序出来。
2025-04-11 11:36:32
931
原创 代码随想录算法训练营第五十七天|图论专题:最小生成树:prim算法、kruskal算法
最小生成树是所有节点的最小连通子图,即:以最小的成本(边的权值)将图中所有节点链接到一起。图中有n个节点,那么一定可以用n-1条边将所有节点连接到一起。那么如何选择这n-1条边就是最小生成树算法的任务所在。prim算法是从节点的角度采用贪心的策略每次寻找距离最小生成树最近的节点并加入到最小生成树中。【选择一个节点开始,小树慢慢成长】prim算法核心就是三步,我称为。刚刚我有讲过“每次寻找距离最小生成树最近的节点并加入到最小生成树中”,那么如何寻找距离最小生成树最近的节点呢?
2025-04-11 11:05:47
352
原创 代码随想录算法训练营第五十六天|图论专题: 并查集,108. 冗余连接、109. 冗余连接2
,这说明在两条边都可以删除的情况下,要删顺序靠后的边!我们来想一下 有向树的性质,如果是有向树的话,只有根节点入度为0,其他节点入度都为1(因为该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点)。
2025-04-08 11:16:05
266
原创 代码随想录算法训练营第五十三天|图论专题: 105. 有向图的完全可达性、106. 岛屿的周长 、110. 字符串接龙
使用邻接表表示有向图。,记录访问过的节点。如果遍历后访问过的节点数为N,说明所有节点都可以从节点 1 到达,输出1;否则输出-1。
2025-04-07 13:48:33
200
原创 代码随想录算法训练营第五十二天|图论专题: 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
1、从左边和后边向中间遍历2、从上边和下边向中间遍历。
2025-04-07 12:49:34
367
原创 代码随想录算法训练营第五十一天|图论专题: 99. 岛屿数量、100. 岛屿的最大面积
本题思路,是用遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。在遇到标记过的陆地节点和海洋节点的时候直接跳过。这样计数器就是最终岛屿的数量。
2025-04-03 11:08:45
163
原创 代码随想录算法训练营第四十八天|单调栈专题: 739. 每日温度、496.下一个更大元素 I 、503.下一个更大元素II
时间复杂度为O(n)。,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。因为要找下一个比当前元素要大的元素,所以栈内元素大小应该从栈顶到栈底是从小到大的,遇到比栈顶元素大的,就要出栈,还是循环结构里出栈。
2025-03-31 10:32:22
190
原创 代码随想录算法训练营第四十六天|回文子串专题: 647. 回文子串、516.最长回文子序列
如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;当s[i]与s[j]不相等,那没啥好说的了,dp[i][j]一定是false。可以往外扩展找回文子串。
2025-03-29 13:12:39
330
原创 代码随想录算法训练营第四十五天|编辑距离专题: 115.不同的子序列 、583. 两个字符串的删除操作、72. 编辑距离
当s[i - 1] 与 t[j - 1]相等时,dp[i][j]可以有两部分组成。一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。一部分是不用s[i - 1]来匹配,个数为dp[i - 1][j]。
2025-03-28 20:16:42
301
原创 代码随想录算法训练营第四十四天|最长序列数组专题: 1143.最长公共子序列、1035.不相交的线 、53. 最大子序和、392.判断子序列
dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;
2025-03-28 20:05:43
168
原创 代码随想录算法训练营第四十三天|最长序列数组专题: 300.最长递增子序列、 674. 最长连续递增序列、 718. 最长重复子数组
dp[i][j] :以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]。即当A[i - 1] 和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1;根据dp[i][j]的定义,dp[i][j]的状态只能由dp[i - 1][j - 1]推导出来。“子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序”。: “以下标i - 1为结尾的A” 标明一定是 以A[i-1]为结尾的字符串 )
2025-03-26 16:47:06
167
原创 代码随想录算法训练营第四十二天|买卖股票专题:188.买卖股票的最佳时机IV、309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费
所以:dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);所以:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);使用二维数组 dp[i][j] :第i天的状态为j,所剩下的最大现金是dp[i][j]在来看看如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来。如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来。
2025-03-25 10:28:00
271
原创 代码随想录算法训练营第四十一天|买卖股票专题:121. 买卖股票的最佳时机、122.买卖股票的最佳时机II、123.买卖股票的最佳时机III
1、确定好dp[j]数组,以及下标含义2、推导出dp[j]公式3、初始化,关键dp[0][0]、dp[0][1],第i天,后面的01表示状态:持有、不持有4、确定遍历顺序:如果求组合问题,不考虑排序顺序,先遍历物品,再遍历背包;求排序问题,考虑前后顺序,先遍历背包,再遍历物品。5、打印dp数组,debug。
2025-03-24 19:57:19
346
原创 代码随想录算法训练营第三十九天|打家劫舍专题:198.打家劫舍、213.打家劫舍II、337.打家劫舍III
1、确定好dp[j]数组,以及下标含义2、推导出dp[j]公式3、初始化,关键dp[0]、dp[1]4、确定遍历顺序:如果求组合问题,不考虑排序顺序,先遍历物品,再遍历背包;求排序问题,考虑前后顺序,先遍历背包,再遍历物品。5、打印dp数组,debug。
2025-03-22 15:46:14
227
原创 代码随想录算法训练营第三十八天|322. 零钱兑换、279.完全平方数、139.单词拆分、背包问题总结篇!
问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);动态规划:416.分割等和子集(opens new window)【01背包】动态规划:1049.最后一块石头的重量 II(opens new window)【01背包】动态规划:494.目标和(opens new window)【01背包】动态规划:518. 零钱兑换 II(opens new window)【无限硬币、完全背包问题,求组和】
2025-03-21 11:05:19
655
原创 代码随想录算法训练营第三十七天|完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)
识别出完全背包问题,与01背包区别是物品是无数个可以无限取注意,完全背包二维dp数组 和 01背包二维dp数组 递推公式的区别,01背包中是。
2025-03-20 11:25:54
155
原创 代码随想录算法训练营第三十六天|1049. 最后一块石头的重量 II 、494. 目标和、474.一和零
跟分割等和子集那题很相似,分割等和子集是将nums数组分成两组之和一样的,dp[j]表示容量j的情况下背包能否装成j价值的我们可以将该问题转化为01 背包问题把所有石头分成两堆,使两堆的重量尽可能相等,求它们的差值。这等价于从stones中找到一个和尽可能接近sum/2的子集,使得这个子集的和最大。dp[j]表示容量(这里说容量更形象,其实就是重量)为j的背包,最多可以背最大重量为dp[j]。注意遍历背包需要从后往前遍历,倒序sum := 0for i := 0;i++ {j-- {
2025-03-19 11:01:49
185
原创 代码随想录算法训练营第三十五天|01背包二维问题和一维问题、416. 分割等和子集
如果背包所载重量为target, dp[target]就是装满 背包之后的总价值,因为 本题中每一个元素的数值既是重量,也是价值,所以,当 dp[target] == target 的时候,背包就装满了。01背包中,dp[j] 表示: 容量(所能装的重量)为j的背包,所背的物品价值最大可以为dp[j]。2、416. 分割等和子集。
2025-03-18 14:46:56
357
原创 代码随想录算法训练营第三十四天|62.不同路径、63. 不同路径 II、343. 整数拆分、96.不同的二叉搜索树
最后我们就可以得到n =4时,搜索二叉树的种类共有dp[0] * dp[3] + dp[1] * dp[2] + dp[2] * dp[1] + dp[3] * dp[0]种。dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为dp[i][j]只有这两个方向过来。dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。例如当n = 4时,
2025-03-17 11:26:11
162
原创 代码随想录算法训练营第三十二天| 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
初始化 dp[0] = 0,dp[1] = 0;
2025-03-17 09:56:32
231
原创 代码随想录算法训练营第三十一天| 56. 合并区间、738.单调递增的数字、968.监控二叉树
需要牢牢掌握首先先按照左边界从小到大进行排序,然后将一个区间先放入答案中,进入for循环进行比较区间值,当前区间的左边界是否在答案中最后一个合并区间之间,如果在的话,则右边界取两者右边界最大值2、 738.单调递增的数字这个题目有技巧,要想到先自己动手模拟一下我们要找到。,这样可以保证结果是最大值。mark。
2025-03-14 10:29:04
169
原创 代码随想录算法训练营第二十九天| 134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列
1sum(gas)sum(cost)-1tank(从某个加油站出发,油量不能变负)。遍历每个加油站,计算tankstarti+1i+1starti+1tankstartitankstart。
2025-03-12 14:32:57
435
原创 代码随想录算法训练营第二十八天| 122.买卖股票的最佳时机II 、55. 跳跃游戏、45.跳跃游戏II 、1005.K次取反后最大化的数组和
假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。那么根据 prices 可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。。方法二、动态规划。
2025-03-11 21:44:49
126
原创 代码随想录算法训练营第二十五天|491.递增子序列 、46.全排列、47.全排列 II、51.N皇后、37.解数独
给你一个整数数组nums,找出并返回所有该数组中不同的递增子序列,递增子序列中。你可以按返回答案。数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。[[4,4]]
2025-03-08 14:08:55
156
原创 代码随想录算法训练营第二十四天|93.复原IP地址 、78.子集、90.子集II
strings.Join 是 Go 语言 strings 包中的一个函数,其主要功能是将一个字符串切片中的所有元素,通过指定的分隔符连接成一个新的字符串。本题也可以不使用used数组来去重,因为递归的时候下一个startIndex是i+1而不是0。startIndex一定是需要的,因为不能重复分割,记录下一层递归分割的起始位置。子集和组合问题都是无序问题,要用startIndex标注。如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,1、93.复原IP地址。3、 90.子集II。
2025-03-07 11:25:44
125
原创 代码随想录算法训练营第二十三天|39. 组合总和、131.分割回文串、 40.组合总和II
那么难究竟难在什么地方呢?切割问题可以抽象为组合问题如何模拟那些切割线切割问题中递归如何终止在递归循环中如何截取子串如何判断回文本题我相信很多同学主要卡在了第一个难点上:就是不知道如何切割,甚至知道要用回溯法,也不知道如何用。也就是没有体会到按照求组合问题的套路就可以解决切割。如果意识到这一点,算是重大突破了。接下来就可以对着模板照葫芦画瓢。但接下来如何模拟切割线,如何终止,如何截取子串,其实都不好想,最后判断回文算是最简单的了。
2025-03-06 12:54:50
378
原创 代码随想录算法训练营第二十二天|77. 组合、216.组合总和III、17.电话号码的字母组合
回溯模板1、77. 组合注意使用startIndex已经选择的元素个数:path.size();所需需要的元素个数为: k - path.size();列表中剩余元素(n-i) >= 所需需要的元素个数(k - path.size())在集合n中至多要从该起始位置 : i <= n - (k - path.size()) + 1,开始遍历这个+1,是因为是坐标之间相减,想得到长度大小就要+12、216.组合总和III找出所有相加之和为 n 的 k 个数的组合。
2025-03-05 11:04:40
266
原创 代码随想录算法训练营第二十一天|669. 修剪二叉搜索树 、108.将有序数组转换为二叉搜索树 、538.把二叉搜索树转换为累加树
如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。同时需要定义一个全局变量pre,用来保存cur节点的前一个节点的数值,定义为int型就可以了。2、 108.将有序数组转换为二叉搜索树。3、 538.把二叉搜索树转换为累加树。分割点就是数组中间位置的节点。1、669. 修剪二叉搜索树。
2025-03-04 10:07:45
163
原创 代码随想录算法训练营第二十天|235. 二叉搜索树的最近公共祖先 、701.二叉搜索树中的插入操作 、450.删除二叉搜索树中的节点
根据二叉搜索树的特性,左边节点的值小于根节点,右节点的值大于根节点,如果遍历到的节点值是在两个节点大小区间内,就是找到了最近公共祖先。
2025-03-03 10:55:36
215
原创 代码随想录算法训练营第十八天|530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先
注意的点就是创建一个pre节点,记录上一次节点数据在 BST 中进行中序遍历,可以得到一个的节点值序列。证明:对于 BST,每个节点的左子树节点值均小于当前节点值,而右子树均大于当前节点值;中序遍历顺序为左 -> 根 -> 右,所以结果必然有序。对于有序数组,任意两个不同元素之间的最小差值必然出现在相邻两个数之间(证明可由反证法得出)。因此,只需要在中序遍历过程中,依次计算相邻两个节点值的差值,取其中的最小值即可。我们可以在中序遍历时用一个指针记录上一次访问的节点(即prev。
2025-03-01 11:50:34
370
原创 代码随想录算法训练营第十七天|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
二叉搜索树,左边节点小于根节点,右边节点大于根节点,经过中序遍历(左中右),即可得到升序数组。·设置前一个节点,进行比较大小,中序遍历中,当前值应该大于前一个值。·将二叉搜索树,中序遍历得到一个数组,来判断是否升序。递归,思路先找最大值的坐标,然后分割左右数组递归。思路:在一棵树上进行操作,然会一棵树就行。3、 700.二叉搜索树中的搜索。4、98.验证二叉搜索树。1、654.最大二叉树。2、617.合并二叉树。
2025-02-28 11:18:09
183
原创 代码随想录算法训练营第十六天|513.找树左下角的值、112. 路径总和、113.路径总和ii、106.从中序与后序遍历序列构造二叉树
只需要记录最后一行第一个节点的数值就可以了。
2025-02-27 16:49:15
156
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人