码随想录算法训练营第62天|卡码网:97. 小明逛公园、127. 骑士的攻击 思路:使用Floyd 算法,目的是解决多源最短路问题,即 求多个起点到多个终点的多条最短路径。用 grid数组来存图,那就把dp数组命名为 grid。grid[i][j][k] = m,表示 节点i 到 节点j 以[1…k] 集合为中间节点的最短距离为m。注意:[1…k] ,表示节点1 到 节点k 一共k个节点的集合。分两种情况:1.节点i 到 节点j 的最短路径经过节点k。
码随想录算法训练营第61天|卡码网:94. 城市间货物运输 I、95. 城市间货物运输 II、96. 城市间货物运输 III 思路:只对 上一次松弛的时候更新过的节点作为出发节点所连接的边 进行松弛就够了,不需要对所有边进行松弛。基于以上思路,如何记录 上次松弛的时候更新过的节点呢?用队列来记录。(其实用栈也行,对元素顺序没有要求)针对:图中边的权值可以有负数,且不存在任何负权回路的情况。(可以为正权回路)
代码随想录算法训练营第59天|卡码网 47. 参加科学大会、94. 城市间货物运输 I 思路依然是 dijkstra 三部曲:1.第一步,选源点到哪个节点近且该节点未被访问过2.第二步,该最近节点被标记访问过3.第三步,更新非访问节点到源点的距离(即更新minDist数组)只不过之前是 通过遍历节点来遍历边,通过两层for循环来寻找距离源点最近节点。这次我们直接遍历边,且通过堆来对边进行排序,达到直接选择距离源点最近节点。1.针对稀疏图,从边的角度使用邻接表进行图存储。2.选源点到哪个节点近且该节点未被访问过。
代码随想录算法训练营第58天|卡码网 117. 软件构建、47. 参加科学大会 思路:使用BFSBFS的实现思路:拓扑排序的过程,其实就两步:1.找到入度为0 的节点,加入结果集2.将该节点从图中移除循环以上两步,直到 所有节点都在图中被移除了。结果集的顺序,就是我们想要的拓扑排序顺序 (结果集里顺序可能不唯一)
代码随想录算法训练营第57天|卡码网 53. 寻宝 prim算法精讲和kruskal算法精讲 prim算法 是从节点的角度 采用贪心的策略 每次寻找距离 最小生成树最近的节点 并加入到最小生成树中。prim算法核心就是三步:1.第一步,选距离最小生成树最近节点2.第二步,最近节点加入生成树3.第三步,更新非生成树节点到生成树的距离(即更新minDist数组)其中:minDist数组 用来记录 每一个节点距离最小生成树的最近距离。
代码随想录算法训练营第56天|卡码网 108.冗余连接、109.冗余连接II 题目描述有一个图,它是一棵树,他是拥有 n 个节点(节点编号1到n)和 n - 1 条边的连通无环无向图(其实就是一个线形图),如图:现在在这棵树上的基础上,添加一条边(依然是n个节点,但有n条边),使这个图变成了有环图,如图:先请你找出冗余边,删除后,使该图可以重新变成一棵树。输入描述第一行包含一个整数 N,表示图的节点个数和边的个数。后续 N 行,每行包含两个整数 s 和 t,表示图中 s 和 t 之间有一条边。输出描述输出一条可以删除的边。
代码随想录算法训练营第55天|卡码网 107. 寻找存在的路径 题目中各个点是双向图链接,那么判断 一个顶点到另一个顶点有没有有效路径其实就是看这两个顶点是否在同一个集合里。最后 isSame(int u, int v) 判断是否是同一个根 就可以了。使用 join(int u, int v)将每条边加入到并查集。如何算是同一个集合呢,有边连在一起,就算是一个集合。
代码随想录算法训练营第51天|卡码网99. 岛屿数量、100. 岛屿的最大面积 本题思路:遇到一个没有遍历过的节点陆地,计数器就加一,然后使用dfs或者bfs把该节点陆地所能遍历到的陆地都标记上。在遇到标记过的节点或遇到海洋节点的时候直接跳过。这样计数器就是最终岛屿的数量。bfs的写法:注意:只要加入队列,立即标记该节点被访问过。以上使用dfs或者bfs的目的都是:把该岛屿所能遍历到的陆地都标记上,不会统计到其他岛屿上。
代码随想录算法训练营第50天|卡码网 98. 所有可达路径 本题我们会有n 个节点,因为节点标号是从1开始的,为了节点标号和下标对齐,我们申请 (n + 1) *( n + 1) 这么大的二维数组。邻接矩阵是从节点的角度来表示图,有多少节点就申请多大的二维数组。还需要存一个n,表示终点,我们遍历的时候,用来判断当 x==n 时候 标明找到了终点。当目前遍历的节点 为 最后一个节点 n 的时候 就找到了一条 从出发点到终止点的路径。首先dfs函数一定要存一个图,用来遍历的,需要存一个目前我们遍历的节点,定义为x。接下来就是将选中的x所指向的节点,加入到 单一路径来。
代码随想录算法训练营第49天|LeetCode 42. 接雨水、84.柱状图中最大的矩形 思路:1.如果当前遍历的元素(柱子)高度小于栈顶元素的高度:就把这个元素加入栈中,因为栈里本来就要保持从小到大的顺序(从栈头到栈底);2.如果当前遍历的元素(柱子)高度等于栈顶元素的高度:要更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。
代码随想录算法训练营第47天|LeetCode 647. 回文子串、516.最长回文子序列 1. LeetCode 647. 回文子串题目链接:https://leetcode.cn/problems/palindromic-substrings/description/文章链接:https://programmercarl.com/0647.回文子串.html视频链接:https://www.bilibili.com/video/BV17G4y1y7z9/1.确定dp数组(dp table)以及下标的含义布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子
代码随想录算法训练营第45天|LeetCode 115.不同的子序列、583. 两个字符串的删除操作、72. 编辑距离 思路:1.确定dp数组(dp table)以及下标的含义dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。2.确定递推公式3.dp数组如何初始化dp[i][0] 表示:以i-1为结尾的s可以随便删除元素,出现空字符串的个数。即,dp[i][0]一定都是1;dp[0][j]:空字符串s可以随便删除元素,出现以j-1为结尾的字符串t的个数。即,dp[0][j]一定都是0;dp[0][0]应该是1。注意:当i或j为0时,子串是空字符串。
代码随想录算法训练营第44天|LeetCode 1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列 1.确定dp数组(dp table)以及下标的含义dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]2.确定递推公式主要就是两大情况: text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同。
代码随想录算法训练营第43天|LeetCode 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组 思路:1.dp[i]的定义dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度2.递推公式位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。注意:这里前提是nums[i] > nums[j],只有这种情况,才能使用dp[j]+1,更新dp[i];也就是说,从0到i-1位置也存在nums[i] <= nums[j]的情况,这时就不考虑以该j位置结尾的最长子序列的长度了dp[j];3.初始化。
代码随想录算法训练营第42天|LeetCode 188.买卖股票的最佳时机IV、309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费 思路:1.确定dp数组以及下标的含义使用二维数组 dp[i][j] :第i天的状态为j,所剩下的最大现金是dp[i][j]。总共2k+1个状态。2.确定递推公式j += 2) {j为奇数是买,偶数是卖的状态。3.dp数组如何初始化j < 2 * k;j += 2) {j为偶数是卖、奇数是买的状态。4.确定遍历顺序从递归公式其实已经可以看出,一定是从前向后遍历,因为dp[i],依靠dp[i - 1]的数值。
代码随想录算法训练营第41天|LeetCode 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II、123.买卖股票的最佳时机III dp[i][0] 表示第i天持有股票所得最多现金;dp[i][1] 表示第i天不持有股票所得最多现金。1️⃣如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0];第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i]那么dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);
代码随想录算法训练营第40天|LeetCode 198.打家劫舍、213.打家劫舍II、337.打家劫舍III 思路:递推公式:第j个房间偷还是不偷偷:dp[j-2]+nums[i]不偷:dp[j-1]