- 博客(54)
- 收藏
- 关注
原创 算法训练营DAY60 第十一章:图论part11
A * 算法的空间复杂度 O(b ^ d) ,d 为起点到终点的深度,b 是 图中节点间的连接数量,本题因为是无权网格图,所以 节点间连接数量为 4。现给定骑士的起始坐标和目标坐标,要求根据骑士的移动规则,计算从起点到达目标点所需的最短步数。如果题目中,给出 多个可能的目标,然后在这多个目标中 选择最近的目标,这种 A * 就不擅长了, A * 只擅长给出明确的目标 然后找到最短路径。小明喜欢去公园散步,公园内布置了许多的景点,相互之间通过小路连接,小明希望在观看景点的同时,能够节省体力,走最短的路径。
2025-09-12 14:40:47
1060
原创 算法训练营DAY60 第十一章:图论part10
输出一个整数,表示从城市 src 到城市 dst 的最低运输成本,如果无法在给定经过城市数量限制下找到从 src 到 dst 的路径,则输出 "unreachable",表示不存在符合条件的运输方案。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。如果发现了负权回路的存在,则输出 "circle"。
2025-09-10 23:02:34
606
原创 算法训练营DAY59 第十一章:图论part09
共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。然而,途中的各个车站之间的道路状况、交通拥堵程度以及可能的自然因素(如天气变化)等不同,这些因素都会影响每条路径的通行时间。接下来为 M 行,每行包括三个整数,S、E 和 V,代表了从 S 车站可以单向直达 E 车站,并且需要花费 V 单位的时间。接下来为 m 行,每行包括三个整数,s、t 和 v,表示 s 号城市运输货物到达 t 号城市,道路权值为 v(单向图)。
2025-09-04 18:07:42
803
原创 算法训练营DAY58 第十一章:图论part08
某个大型软件项目的构建系统拥有 N 个文件,文件编号从 0 到 N - 1,在这些文件中,某些文件依赖于其他文件的内容,这意味着如果文件 A 依赖于文件 B,则必须在处理文件 A 之前处理文件 B (0 <= A, B <= N - 1)。3、更新minDist数组:这里需要遍历节点,找到没被访问过且从cur->k节点存在路径且minDist[cur]+grid[cur[k]<minDist[k]的节点才会用来更新minDist。引入一个记录每个节点的入度的数组,第i个位置存储节点i的入度;
2025-09-04 11:05:00
935
原创 算法训练营DAY57 第十一章:图论part07
minDist数组里的数值初始化为最大数,现在还没有最小生成树,默认每个节点距离最小生成树是最大的,这样后面我们在比较的时候,发现更近的距离,才能更新到minDist数组上。这么写,最后更新的逻辑是 parent[1] = 2, parent[1] = 3, parent[1] = 4,最后只能记录节点1与节点4相连,其他相连情况都被覆盖了。,那就是 parent[2] = 1, parent[3] = 1, parent[4] = 1 ,这样才能完整表示出节点1与其他节点都是链接的,才没有被覆盖。
2025-08-11 22:22:57
1696
原创 算法训练营DAY56 第十一章:图论part06
节点3 的入度为 2,但在删除边的时候,只能删 这条边(节点1 -> 节点3),如果删这条边(节点4 -> 节点3),那么删后本图也不是有向树了(因为找不到根节点)。输入一个有向图,该图由一个有着 n 个节点(节点编号 从 1 到 n),n 条边,请返回一条可以删除的边,使得删除该条边之后该有向图可以被当作一颗有向树。,如果是有向树的话,只有根节点入度为0,其他节点入度都为1(因为该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点)。如果有多个答案,请删除标准输入中最后出现的那条边。
2025-08-07 14:54:04
478
原创 算法训练营DAY55 第十一章:图论part05
我们的目的只需要知道这些节点在同一个根下就可以,所以对这棵多叉树的构造只需要这样就可以了,除了根节点其他所有节点都挂载根节点下,这样我们在寻根的时候就很快,只需要一步,如果我们想达到这样的效果,就需要。因为 find 函数向上寻找根节点,father[u] 表述 u 的父节点,那么让 father[u] 直接获取 find函数 返回的根节点,这样就让节点 u 的父节点 变成根节点。如果存在,输出 1;我们需要 father[C] = C,即C的根也为C,这样就方便表示 A,B,C 都在同一个集合里了。
2025-08-06 22:52:38
792
原创 代码训练营DAY53 第十一章:图论part04
在搜索的过程中,我们可以枚举,用26个字母替换当前字符串的每一个字符,在看替换后 是否在 strList里出现过,就可以判断 两个字符串 是否是链接的。给定一个有向图,包含 N 个节点,节点编号分别为 1,2,...,N。当前访问的节点如果是 true ,说明是访问过的节点,那就终止本层递归,如果不是true,我们就把它赋值为true,因为这是我们处理本层递归的节点。你可以假设矩阵外均被水包围。当我们需要搜索一条可行路径的时候,就需要回溯操作了,因为没有回溯,就没法“调头”, 如果不理解的话,去看我写的。
2025-08-05 08:45:07
667
原创 代码训练营DAY52 第十一章:图论part03
题目描述给定一个由 1(陆地)和 0(水)组成的矩阵,岛屿指的是由水平或垂直方向上相邻的陆地单元格组成的区域,且完全被水域单元格包围。孤岛是那些位于矩阵内部、所有单元格都不接触边缘的岛屿。现在你需要计算所有孤岛的总面积,岛屿面积的计算方式为组成岛屿的陆地的总数。输入描述第一行包含两个整数 N, M,表示矩阵的行数和列数。之后 N 行,每行包含 M 个数字,数字为 1 或者 0。输出描述输出一个整数,表示所有孤岛的总面积,如果不存在孤岛,则输出 0。输入示例输出示例:1。
2025-08-04 22:09:11
691
原创 算法训练营DAY51 第十一章:图论part02
给定一个由 1(陆地)和 0(水)组成的矩阵,计算岛屿的最大面积。岛屿面积的计算方式为组成岛屿的陆地的总数。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。后续 N 行,每行包含 M 个数字,数字为 1 或者 0,表示岛屿的单元格。输出一个整数,表示岛屿的最大面积。后续 N 行,每行包含 M 个数字,数字为 1 或者 0。输出一个整数,表示岛屿的数量。
2025-08-04 20:13:42
331
原创 算法训练营DAY50 第十一章:图论part01
给定一个有 n 个节点的有向无环图,节点编号从 1 到 n。请编写一个程序,找出并返回所有从节点 1 到节点 n 的路径。输出所有的可达路径,路径中所有节点的后面跟一个空格,每条路径独占一行,存在多条路径,路径输出的顺序可任意。后续 M 行,每行包含两个整数 s 和 t,表示图中的 s 节点与 t 节点中有一条路径。当目前遍历的节点x 为 最后一个节点 n 的时候 就找到了一条 从出发点到终止点的路径。第一行包含两个整数 N,M,表示图中拥有 N 个节点,M 条边。最后要注意回溯,撤销添加节点的操作。
2025-08-04 10:10:40
433
原创 算法训练营DAY49 第十章 单调栈part02
长就是通过柱子的高度来计算,宽是通过柱子之间的下标来计算,栈里就存放下标就行,想要知道对应的高度,通过height[stack.top()] 就知道弹出的下标对应的高度了。因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。理解这一点,对单调栈就掌握的比较到位了。
2025-08-03 11:20:48
855
原创 算法训练营DAY48 第十章 单调栈part01
数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。接下来我们用temperatures = [73, 74, 75, 71, 71, 72, 76, 73]为例来逐步分析,输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
2025-08-02 17:57:25
901
原创 算法训练营DAY46 第九章 动态规划part13
给你一个字符串s,请你统计并返回这个字符串中的数目。是正着读和倒过来读一样的字符串。是字符串中的由连续字符组成的一个序列。s = "abc"3三个回文子串: "a", "b", "c"s = "aaa"66个回文子串: "a", "a", "a", "aa", "aa", "aaa"动态规划思路1、确定dp数组及下标含义如果定义dp[i] 为 下标i结尾的字符串有 dp[i]个回文串的话,会发现很难找到递归关系。dp[i] 和 dp[i-1] ,dp[i + 1] 看上去都没啥关系。
2025-08-02 10:55:00
986
原创 算法训练营DAY45 第九章 动态规划part12
115.不同的子序列给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)题目数据保证答案符合 32 位带符号整数范围。思路动规五部曲1、dp数组及下标含义dp[i][j]:以i-1结尾的s子序列中出现j-1为结尾的t的个数2、确定递推公式判断s[i-1]与t[i-1]是否相同,如果。
2025-08-01 18:21:26
878
原创 算法训练营DAY42 第九章 动态规划part09
如果i为1,第1天买入股票,那么递归公式中需要计算 dp[i - 1][1] - prices[i] ,即 dp[0][1] - prices[1],那么大家感受一下 dp[0][1] (即第0天的状态二)应该初始成多少,只能初始为0。那么dp[i][0] = max(dp[i - 1][0], dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]);设计一个算法来计算你所能获取的最大利润。dp[i][j],第i天状态为j,所剩的最多现金为dp[i][j]。
2025-07-26 01:17:53
636
原创 算法训练营DAY44 第九章 动态规划part11
要找最大的连续子序列,就应该找每一个i为终点的连续最大子序列。所以在递推公式的时候,可以直接选出最大的dp[i]。
2025-07-26 00:50:38
905
原创 算法训练营DAY43 第九章 动态规划part10
连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。但dp[i][0] 和dp[0][j]要初始值,因为 为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1;根据dp[i][j]的定义,dp[i][0] 和dp[0][j]其实都是没有意义的!
2025-07-25 15:54:38
817
原创 算法训练营DAY41 第九章 动态规划part08
这两种情况要取最大值,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);这两种情况要取最大值,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);这两种情况要取最大值,dp[i][0] = max(dp[i - 1][0], dp[i-1][1]-prices[i]);dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。
2025-07-23 18:58:51
741
原创 代码训练营DAY39 第九章 动态规划part07
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。如果不偷当前节点,那么左右孩子就可以偷,至于到底偷不偷一定是选一个最大的,所以:val2 = max(left[0], left[1]) + max(right[0], right[1]);每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
2025-07-22 23:27:01
697
原创 算法训练营DAY38 第九章 动态规划part06
问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);动态规划:416.分割等和子集(opens new window)动态规划:1049.最后一块石头的重量 II(opens new window)动态规划:494.目标和(opens new window)动态规划:518. 零钱兑换 II(opens new window)动态规划:377.组合总和Ⅳ(opens new window)
2025-07-22 00:47:38
784
原创 算法训练营DAY37 第九章 动态规划 part05
分析dp[1][4]的推导过程,需要对比:目前背包容量为4,如果空出物品1的重量3,剩余重量为1的背包的最大价值+物品一的价值dp[i][j - weight[i]] + value[i];所以递推公式为dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]);dp[i][j]:使用 下标为[0, i]的coins[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种组合方法。有N件物品和一个最多能背重量为W的背包。
2025-07-21 23:08:33
2080
原创 算法训练营DAY36 第九章 动态规划part04
1049. 最后一块石头的重量 II - 力扣(LeetCode)有一堆石头,每块石头的重量都是正整数。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:benti如果 x == y,那么两块石头都会被完全粉碎;如果 x!= y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。输入:[2,7,4,1,8,1]
2025-07-20 18:50:20
883
原创 代码训练营DAY35 第九章 动态规划part03
如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。有递归公式,可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。当。
2025-07-18 22:09:00
659
原创 算法训练营DAY34 第九章 动态规划part02
保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。所以递推公式:dp[i] += dp[j - 1] * dp[i - j];每个点来自他的上方或者左方,所以路径数量等于上方位置的数量加左方位置的数量。每个点来自他的上方或者左方,所以路径数量等于上方位置的数量加左方位置的数量。j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量。
2025-07-16 19:00:35
2668
原创 算法训练营DAY32 第九章 动态规划part01
动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。动态规划中dp[j]是由dp[j-weight[i]]推导出来的,然后取max(dp[j], dp[j - weight[i]] + value[i])。
2025-07-12 22:35:13
617
原创 DAY31
从后往前遍历,下一个数字比当前数字大(不满足单调递增的条件),就让下一个数字减一,当前数字的位数记录到flag;1、如果right小于下一个区间的左边界,把当前left,right放入res;最后在主函数中需要判断根节点是否为无覆盖0,如果无覆盖还需要额外加一个摄像头;2、如果right大于下一个区间的左边界,把right更新为下一个区间的右边界;每个节点有三种状态0、无覆盖1、有摄像头2、有覆盖。叶子节点的子节点为NULL,这个节点需要视为已覆盖。给出一个区间的集合,请合并所有重叠的区间。
2025-07-11 21:07:25
598
原创 算法训练营DAY30 第八章 贪心算法 part04
用双指针的思想引入left、right指针,right用当前字符的最晚出现位置更新,当i==right时,意味着可以收获了,res收获right-left+1作为每段字符串的长度;在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被引爆。然后for循环i从1开始,(第二个),如果右边的元素左边界小于左边的元素右边界,那这两个元素必定相交,所以count++;返回一个表示每个字符串片段的长度的列表。
2025-07-11 18:49:50
502
原创 算法训练营DAY29 第八章 贪心算法 part02
134. 加油站思路如果总消耗大于总油量,那肯定无法完成绕圈令rest=gas-cost;循环中累加这个rest记为curSUM;如果curSum出现负数,让start记为i+1;curSum归零,重新计数;遍历完后如果能完成绕圈,start记录的就是答案起始位置。
2025-07-09 00:09:24
377
原创 代码训练营DAY28 第八章 贪心算法 part02
cover记录下一步能达到的最远距离(这个距离与数组长度相比,决定停止步数);curDis用来记录当前位置能到达的最远范围;用来遍历寻找最大cover,当i==curDis意味着需要走下一步,而每次更新curdis为能走到的最远距离cover的上一轮循环会判断cover是否能到达终点;循环中记录第二天价格减去当天价格得到每天的收益,这个收益可为正数也可为负数;给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个位置。
2025-07-08 04:01:02
383
原创 算法训练营DAY25 第七章 回溯算法 part04
然后在树层级别去重(i>0&&nums[i]==nums[i-1]&&used[i-1]==false)题目给定的数组已经无重复,那只需要标记当前树枝已经使用过的元素;这里需要判断一个元素是否被使用过,考虑到数组是无序的,使用哈希表的思想unordered_set;if的条件设置为(比较当前nums[i]与path的尾元素)(nums[i]是否已经使用过)给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。注意这题给定的数组不一定是有序的,且不能擅自排序,否则可能会多输出结果。
2025-07-06 20:35:43
339
原创 算法训练营DAY24 第七章 回溯算法part03
而==false意味着nums[i-1]这个节点的深度方向遍历完成,此时nums[i]==nums[i-1]不需要再遍历一次;示例: 输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]注意在for循环中要加入if判别(i>0&&nums[i]==nums[i-1]&&used[i-1]==false)给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
2025-07-05 18:28:02
953
原创 算法训练营DAY23 第七章 回溯算法part02
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。用来记录给定数组的元素是否被使用过,使用过就used[i]=true;当分割下标index==s.size();参数:给定数组,目标和,当前和,当前下标,数组使用记录表;参数:给定的数组,目标和,当前和,当前下标。
2025-07-04 01:20:19
740
原创 算法训练营DAY22 第七章 回溯算法part01
for循环,引入i=0,i<letters.size(),i++;循环中s.push_back(lettes[i]),然后进入下一层递归,注意回溯s.pop_back();注意回溯,sum-=i;因为输入的是字符串,需要int num转换输入的字符串成整形,只需要num=digits[index[-'0';示例 2: 输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]]回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。
2025-07-03 19:29:18
700
原创 算法训练营DAY21 第六章 二叉树part08
如果当前结点的值小于下限,那么需要向该节点的右儿子递归,为了看右儿子是否有在区间内的部分,并返回满足区间的子树根节点;如果当前值大于上限,就需要向该节点的左儿子递归,为了看左儿子满足区间的部分,并返回满足区间的子树根节点;按照右中左的顺序遍历,先找到最右边的最大的元素,用pre记录这个最大元素,上一层递归会把这个值加到上一层的root节点,实现层层累加。注意在普通二叉树的属性中,我用的是一般为后序,例如单纯求深度就用前序,求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
2025-07-01 16:33:20
273
原创 算法训练营DAY20 第六章 二叉树part07
当root的值比p、q的值都大,就向左递归,用left接收返回值,当left不为空,就return left;当root的值比p、q的值都小,就向右递归,用right接收返回值,当right不为空,就return right;当root的值大于val,向左递归,用root->left接收返回值(node);5)左右孩子都不为空,将左子树的头结点(左孩子)放到右子树最左的节点的左孩子的位置。3)左孩子为空,右孩子不为空,删除节点,右孩子补位;4)右孩子为空,左孩子不为空,删除节点,左孩子补位;
2025-06-30 18:24:31
247
原创 算法训练营DAY17 第六章 二叉树part06
所以当双指针的值相等时,记录该元素的出现次数,比较该元素出现的次数与最大出现次数,若等于则将这个数值放入res数组,若次数大于最大次数,清除res后将该元素放入res。用双指针法,中序遍历,cur会先移动到最左边的元素,设置中序激活条件pre!=NULL,激活的情况下,比较res与目前cur与pre的差值取小的那个;中间部分,对left和right的情况分类讨论返回不同的节点(left、right、root、NULL)四种情况。用后序遍历回溯的思想,从下边开始搜索p、q,3、确定单层递归逻辑。
2025-06-28 17:32:16
161
原创 算法训练营DAY17 第六章 二叉树part05
(举一个例子,当当前节点遍历到最左边的节点,把最左边的节点赋予pre,下一步当前节点会去到pre的根节点,这时候比较当前节点与下方的pre节点,如果当前节点root比下方的pre小,那么就返回false;再下一步将这个根节点赋予pre,当前节点去到右节点,右节点(当前节点)比上方的pre小,返回false;再下一步右节点赋予pre,当前节点去到根节点的根节点,继续比较.....如果传入数组的大小为1,那说明传入的是叶子节点,需要定义一个新节点,将数组中的数值赋予这个节点。3)右边的数组作为右子树的数组。
2025-06-27 17:41:41
468
原创 算法训练营DAY16 第六章 二叉树 part04
递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。递归方法采用前序遍历,但要注意需要回溯,(返回上一层时,深度减一)保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。本题还需要类里的两个全局变量,maxDepth用来记录最大深度,res记录最大深度最左节点的数值。左/右儿子放入当前路径,差值更新,递归下一个,差值回溯,当前路径回溯;遇到叶子节点时,统计最大深度,如果深度够大,记录叶子节点val。参数包括根节点,count记录路径和与目标的差值;
2025-06-26 19:00:08
389
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅