- 博客(52)
- 收藏
- 关注
原创 代码随想录算法训练营第四天|链表part02
遍历一遍链表 统计有多少个节点 然后再计算出被删除节点前一个节点的编号。事实上 有更好的方法 这题是典型的应用快慢指针的方法。遍历到被删除节点前一个节点 然后再进行删除操作。说明此时 在相遇的地方定义一个指针index1。两者一起走 他们相遇的地方就是环的入口。快指针每次走两格,慢指针每次走一格。19.删除链表的倒数第N个节点。24. 两两交换链表中的节点。头定义一个指针index2。先分别求两个链表的长度。然后比较长度 长的先走。从头到环入口的距离为x。从入口到相遇的距离为y。从相遇到入口的距离为z。
2025-09-03 21:37:27
258
原创 代码随想录算法训练营第二天| 209.长度最小的子数组
采用滑动窗口,窗口的终点不断往后滑,每当当前窗口的值超过或等于target时,就把窗口前端也尝试往前滑。这里又是我看错了 求的确实是连续子数组 ,但是要求子数组值大于或等于目标值,而不是等于。则寻找满足条件的f(n+k)-f(n)=val的k ,然后返回最小值的k。每圈都会经过从左到右 从上到下 从右到左 从下到上的顺序。错误地方:求的是子数组,而不是最小的连续子数组。思路: 定义f(n)表示数组前n项的和。这也是暴力解法,最终运行超时。209.长度最小的子数组。
2025-09-03 15:35:34
328
原创 代码随想录算法训练营第六十天|图论part10
队列优化版的福特算法 ,统计节点入队次数。如果节点入队次数超过n,说明出现环。普通版的福特算法,考虑第n次松弛是否会出现更短的路径。每轮松弛都要基于上一轮的minDist数组,所以要复制一份。Bellman_ford 队列优化算法(又名SPFA)本题的关键是对松弛的次数有严格要求,不能多松弛。bellman_ford之单源有限最短路。bellman_ford之判断负权回路。因为在松弛的过程中 做了很多无用功。所以用队列来记录需要松弛的边。
2025-08-10 16:00:08
293
原创 代码随想录算法训练营第五十九天|图论part9
(Function Call Operator Overload),它让一个对象可以像函数一样被调用。dijkstra(堆优化版)精讲。1.选取距离源节点并且未访过的节点。Container:底层容器类型。对所有边进行n-1次松弛操作。现在改为用邻接链表去存储图。2.标记选取节点为已访问。带有负权值的单源最短路径。Compare:比较器。
2025-08-10 14:12:24
402
原创 代码随想录算法训练营第五十七天|图论part7
不能初始化为0 这样不存在的边的权值为0 ,应该把不存在的边的权值设为最大值!“方括号抓变量,圆括号写参数,箭头指返回,花括号干正事。”,本质上编译器帮你生成一个未命名的。普利姆算法用于求最小生成树。kruskal算法精讲。1.选择离树最近的点。
2025-07-31 17:43:48
345
原创 代码随想录算法训练营第五十六天|动态规划part6
情况2:不存在入度为2的节点 此时存在环对于存在环。应该找出哪条边使得构成环 可以通过并查集来找。说明这个节点存在冗余的边(存在两个父节点)情况1: 存在入度为2的节点。此处需要判断删除哪条边。109.冗余连接II。
2025-07-30 17:03:10
197
原创 代码随想录算法训练营第五十三天|图论part4
没有visited记录已经访问过的节点 ,导致陷入死循环。转换为求无权图两节点的的最短路径。遍历所有陆地,统计其四个方向 如果是海 则边数+1。逐渐遍历看第一个节点能不能到达其他节点。把每个字符串看成图的一个节点。105.有向图的完全可达性。不要用惯性思维用深搜。
2025-07-25 17:36:09
425
原创 代码随想录算法训练营第五十二天|图论part3
与岛屿面积差不多,区别是再dfs的时候,如果碰到越界的,需要用一个符号标记这不是孤岛再continue。main函数中dfs结束后 得到是不是孤岛 如果是孤岛 record里的坐标全部标为0。与上体差不多,添加一个变量record 本次深搜或广搜遍历到的岛屿。然后求第一边界出发经过的节点与第二边界出发经过的节点的交集。用逆向思维,从第一边界出发,水往高处流看能经过哪些节点。从第二边界出发,水往高处流 看能经过哪些节点。第二步 遍历所有海洋 相邻岛屿面积加起来。第一步 统计每块岛屿的面积。
2025-07-23 16:33:35
718
原创 代码随想录算法训练营第五十一天|图论part2
先将岛屿数据存储到二维矩阵,遍历二维矩阵,遇到1,则统计数量+1,然后将该岛屿四个方向的岛屿都标为已访问。找到一个岛屿 然后用广度或者深度优先搜索去遍历周围相连的岛屿,每有一个相连,面积加1。while队列不为空,获取队首节点,处理当前节点逻辑,符合条件的入队。新建一个队列,当前节点入队,100.岛屿的最大面积。
2025-07-16 18:49:18
1275
原创 代码随想录算法训练营第五十天|图论part1
(x给别人,所以是向着out的)(给x,所以是向着x的)98. 所有可达路径。3.处理当前节点逻辑。
2025-07-16 15:11:35
345
原创 代码随想录算法训练营第四十九天|单调栈part2
所盛水是 1的左右两边柱子的最小值 然后再减去1的柱子里边原本的高度。宽度的计算在于 寻找当前柱子左右两边第一个比它小的 l和r。考虑每个柱子的高度为高,然后计算最大的宽度,再计算面积。height = [4,2,0,3,2,5]为例。先求每根柱子左右边第一个高的。左右两边都不为-1才能接住水。左右两边都不为-1的置为1。84.柱状图中最大的矩形。对于1 里边都能盛水。然后统计所有的水 j。比较上述面积的最大值。
2025-07-14 20:39:26
269
原创 代码随想录算法训练营第四十八天|单调栈part1
用单调栈的思路,实际上就是遍历数组2 ,找右边第一个比当前大的元素,这与上题一样,然后再判断这个元素是否在数组1中出现过。多循环一遍 ,第二遍循环只出栈,不入栈。单调栈,栈里存放的元素单调递增。496.下一个更大元素 I。503.下一个更大元素II。
2025-07-14 14:01:38
578
原创 代码随想录算法训练营第四十六天|动态规划part13
注意:这里是错的 考虑bba 或者abb 这里应该是dp【i】【j】=max(dp【i】【j-1】,dp【i+1】【j】)dp【i】【j】依赖于dp【i+1】【j-1】因此 i从后往前遍历,j从前往后遍历。以dp【i】表示以s【i】结尾的回文子串的个数,发现递推公式推导不出来此路·不通。以dp【i】【j】表示s【i】到s【j】的回文子串的个数,递推公式也推不出。dp[i][j]表示s【i】到s【j】的最长回文子序列的长度。正确 dp【i】【j】表示s【i】到s【j】是否为回文串。最后一天动态规划 开心!
2025-07-04 17:08:24
325
原创 代码随想录算法训练营第四十五天|动态规划part12
int a=min(dp[i-1][j]+1,dp[i][j-1]+1) //删除word1或word2。dp[i][j]=min(a,dp[i-1][j-1]+2) //两个都删除。定义dp[i][j]表示 s 0-i-1与t 0-j-1不同的子序列的个数。所以dp[5][4]=dp[4][4] 也就是不考虑s[4]dp[i][j]=dp[i-1][j-1] //不同考虑这两个字母。3.初始化dp[i][0]与dp[0][j]4.遍历顺序 正序遍历。动态规划解这个太棒了。
2025-07-03 17:33:38
272
原创 代码随想录算法训练营第四十四天|动态规划part11
1143.最长公共子序列思路:其实就是求两个字符串的最长公共子序列的长度与公共子数组的区别是可以不连续 ,顺序对就可以状态转移方程不一样定义dp[i][j]表示text1的0到i-1与text2的0到j-1的最长公共子序列的长度否则等于max(dp[i-1][j],dp[i][j-1])1035.不相交的线与上题一样53. 最大子序和。
2025-07-03 16:01:05
205
原创 代码随想录算法训练营第四十三天|动态规划part10
300.最长递增子序列错误解答:dp[i]表示前i个元素的最长递增子序列的长度错误原因,这里是默认第一个元素就是最长递增子序列的一部分了正确解答:1.明确dp数组含义dp[i]表示以nums【i】为结尾的最长递增子序列的长度2.转移方程3.初始化dp【0】=14.遍历顺序正序遍历注意!!!!!!!!!初始化dp数组要为1,不能初始化为0,因为dp数组的含义是以nums【i】为结尾的最长递增子序列的长度,所以一开始就是1,自身为子序列,就是1。
2025-07-02 19:21:16
334
原创 代码随想录算法训练营第四十二天|动态规划part9
上一天的持有dp[i-1][2j+1] ,上一天的不持有今天持有是 dp[i-1][2j]-prices[i] 两者求最大值。上一天的不持有dp[i-1][2j+2] 上一天持有,今天不持有 dp[i-1][2j+1]+prices[i]dp[i][2j+2]第i天第j次不持有 ,有两种情况 继续保持上一天的不持有 或者上一天持有,今天不持有。dp[i][2j+1]第i天第j次持有,有两种情况 继续保持上一天的持有 或者上一天不持有,今天持有。遍历顺序 :正序遍历。
2025-07-02 16:51:48
237
原创 代码随想录算法训练营第四十一天|动态规划part8
121. 买卖股票的最佳时机思路:方法1:暴力解,超时方法2:动态规划动态规划解决一系列股票买卖问题一般定义dp【i】【0】表示第i天不持有股票的最大现金dp【i】【1】表示第i天持有股票的最大现金那么最终的的答案就是dp【prices.size()-1,0】状态转移公式:遍历顺序 正序遍历122.买卖股票的最佳时机II。
2025-06-30 17:11:50
406
原创 代码随想录算法训练营第三十九天|动态规划part7
定义dp【i】表示前i家能偷到的最多前,则dp【i】=max{dp【i-2】+nums【i】,dp【i-1】}返回值呢 偷当前节点与不偷当前节点 所能偷的最大值。先遍历左右孩子,最后遍历父节点,所以是中序遍历。所以肯定有一个函数 传入的参数是当前根节点。这是一道二叉树的结构,需要遍历二叉树。去头意味着头不偷,去尾意味着尾不偷。当前家偷与不偷取决于前两家的状态。1.去头 ,则转换为打家劫舍1。2.去尾,转换为打家劫舍2。最终结果取情况12的最大值。213.打家劫舍II。包含着取头,尾巴不取。
2025-06-30 15:32:35
225
原创 代码随想录算法训练营第三十八天|动态规划part6(完全背包2)
字符串有函数s.substr(i,n)表示从位置i开始分割长度为n的字符串。完全背包 那么是排列问题还是组合问题 这是排列问题 所以先遍历背包。还存在另一个问题 没有任何一种硬币组合能组成总金额。需要注意的是:完全背包的两层for循环强调先后顺序。由于是完全背包 ,所以遍历顺序是正序。但是排列 或组合问题是强调先后顺序的。这道题可以理解为一个完全背包问题。dp[i]表示前i个字符能被分割。那么需要考虑 背包容量 物品。背包容量呢 就是字符串s的长度。其实也就是没更新 dp。这道题跟上题几乎一样。
2025-05-12 23:59:05
289
原创 代码随想录算法训练营第三十七天-2|动态规划part2
那么本题 先遍历背包 即在背包容量为j下能有多少种装法(包含了不同排列顺序了的)因为上题的遍历先遍历物品 所以隐含了一个物品的排列顺序 一种特定的排列顺序。事实上 这道题类似于01背包问题的目标和 这是一道完全背包的目标和。用dp【i】【j】表示从0-i任选硬币 有多少种方法装满背包j。这道题与上题的零钱兑换二很像 区别在于 这是排列问题。区别在于遍历顺序为从头到尾遍历。注意01背包与完全背包的区别。518. 零钱兑换 II。377. 组合总和 Ⅳ。
2025-05-08 21:35:14
318
原创 代码随想录算法训练营第三十七天|动态规划part4
dp【m-x】【n-y】+1表示装物品i dp【m】【n】表示不装物品i。定义dp【m】【n】表示不超过m个0和n个1的情况下最大子集的长度。dp[i][j]表示从0-i块石头往容量为j的包里装 的最大价值。这里涉及到更新dp【j】顺序的问题 小的j会影响大的j。然后dp[j]表示容量为j的背包能装的石头的最大价值。每个物品的重量为石头的重量 价值也为石头的价值。那么sum-dp【j】就是另一个背包的石头的重量。d的j不会影响小的j 所以应该先更新大j。用正的一堆减负的一堆等于目标。
2025-04-26 12:21:17
405
原创 代码随想录算法训练营第三十五天|动态规划part3
这里的第二层for循环 j写成大于等于0了 实际上应该满足 j-nums[i]>=0\。若dp【target】==target则返回true。看作01背包 装进背包使得其价值总和为target。也就是在数组中找任意个数使得其总和为target。dp【j】表示装进容量为j的背包的最大价值。先求数组和 将数组和除2得target。把数组元素的值看作重量与价值。416. 分割等和子集。
2025-04-22 17:51:16
238
原创 代码随想录算法训练营第三十四天|动态规划part2
j的遍历出现问题 j最大遍历到i-1 就行了。从mn走到endpositon 的不同路径。知道递推公式 还是用了很多时间来修改。理解题目错了 以为从右下角往左上角跑。考虑左右子树的数量 以三为例。定义dp【m】【n】的含义。左子树可以是2 右子树是0。左子树可以是0 右子树是2。或者左子树是1 右子树是1。63. 不同路径 II。实际是从左上角往右下角跑。
2025-04-21 23:27:15
196
原创 代码随想录算法训练营第三十二天|动态规划part1
如果给定的数组大小是3 那么爬上顶层相当于爬上第size层楼梯。第一明确ans[i]的含义 表示爬上第i层需要的代价。所以ans的索引最大值是size。746. 使用最小花费爬楼梯。509. 斐波那契数。
2025-04-17 23:47:59
191
原创 代码随想录算法训练营第三十一天|贪心算法part5
这种考虑要确定先后顺序 情况二跟三有重叠部分 要先满足条件二 当前节点装摄像头。应该从叶节点像父节点遍历 所以用的是左右中即后序遍历(这种实际上是递归)左右孩子至少有一个没有被覆盖 当前节点 装摄像头。左右孩子都被覆盖 那么当前节点应该不装摄像头。左右孩子至少有一个装摄像头 当前节点被覆盖。代码随想录的解法也差不多 但是更加精简。确定遍历顺序是从后往前 这点很重要。空节点应该要返回 2 被覆盖。第二部:确定处理回溯的逻辑。738.单调递增的数字。第一步:确定遍历顺序。但是有些可以统一考虑。
2025-04-16 15:54:07
269
原创 代码随想录算法训练营第三十天|贪心算法part4
那么如何考虑气球重叠呢 排序后考虑相邻的区域 如果前一个的右小于或等于后一个的左 则判断为重叠 然后这两个视为一个整体 更新右边界 再用这个右边界与下一个气球相比。而不是强制intervals[i][1]=intervals[i-1][1];第二多个气球重叠的情况 考虑射的最多的地方 可以射几只气球。可以肯定的是 没有重叠的气球 一定需要一只弓箭。我在移除重叠的时候 应该尽可能让右边界小。排序后判断是否有重叠 重叠后更新右边界。用right来确定结束的位置。错误原因:在于右边界的更新。
2025-04-16 12:28:46
362
原创 代码随想录算法训练营第二十八天|贪心算法part2
相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。这里错误的地方在于更新最大覆盖范围总是用当前元素的值去更新 事实上最大覆盖范围可能是之前元素的值。假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。思路:跳不过去的坎是0 我本来想收集所有0的下标 然后判断每一个带0的下标是否可以跳过去。用覆盖范围去求解 每遍历一个单位 更新全局覆盖范围。
2025-04-08 14:29:55
1455
原创 代码随想录算法训练营第二十七天|贪心算法part1
时间复杂度有点高 贪心策略是 尽量较少饼干的浪费 即大饼干应该尽可能分给胃口大的孩子 所以可以从后往前遍历。遇到正数加到结果当中更新全局最大值 遇到负数也加到结果中 如果此时结果小于0则让结果归零。用preDiff 与curDiff来比较 两者乘积满足小于0即可更新结果。考虑只有一个元素和全是负数的特殊情况。考率只有两个元素的情况。
2025-04-07 20:54:40
273
原创 代码随想录算法训练营第二十五天|回溯法part4
快速从一个vector中查找指定元素 用find(nums.begin(),nums.end((),target)返回迭代器。排列强调顺序 我这里用了一个set set无序的 不能用这个来收集路径。因为不能改变原来的顺序 所以之前的去重不能直接套用 需要做以下改变。下面的代码 会求出所有长度大于等于二的子序列 并没有递增。本题的难点在于不能改变原序列的顺序,所以用排序是错的。在回溯算法中 当前递归层的for循环算作同一层。每层不能有重复元素 用一个set来记录。
2025-04-02 16:49:08
287
原创 代码随想录算法训练营第二十四天|回溯法part03
用一个path收集结果,path.size等于4的时候 作为终止条件,要处理path总size不等于s.size的情况。然后回溯到1 现在开始在22里选择第二个2 但是 这种情况要跳过 if nums[i-1]==nums[i]不行 因为这样会错过往深了递归的情况 所以 只有 nums[i-1]=false的时候 才能continue。错误原因:回溯的时候 没有处理 use[i]=false;如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,第一次先选1 在剩下的22里递归 最终得到1,2,2。
2025-04-01 21:08:14
308
原创 代码随想录算法训练营第二十三天|回溯法part2
判断startIndex到i之间的子串是否是回文串 如果是加入 继续更新startindex 继续下一轮判断。对于第二个1 前一个1没有被使用 并且第二个1与第一个1相等,此时不考虑这种情况 continue。used[i - 1] == false为什么是false的解释。另一个 可能出现 223 322这样的情况。错误之处:会出现重复的答案,没有去重。考虑112 目标值等于3。
2025-04-01 17:18:24
203
原创 代码随想录算法训练营第二十二天|回溯法part1
思路与上题一样 ,不可能用k个for循环的,用递归思路。用递归 递归决定深度 for循环决定宽度。思路:暴力解,但是会套k个for循环。以树的数据结构来理解回溯法。17.电话号码的字母组合。怎么写这k个for循环呢。216.组合总和III。3.确定for循环内容。
2025-03-17 14:56:08
238
原创 代码随想录算法训练营第二十一天
将有序数组转换为二叉搜索树思路:利用二叉搜索树的特点 ,当前节点的左右子树都是二叉搜索数,从数组中间把当前数组一分为二,中间元素作为根节点,递归构建左右子树。把二叉搜索树转换为累加树遍历一次二叉树,得到升序排列的结果。结果从后往前累加,再次遍历二叉树,把累加值赋给当前节点二叉搜索树的中序遍历(左中右)可以得到按小到打排列的顺序,若是按照右中左的顺序遍历,可以得到从大到小排列的顺序。
2025-03-10 16:36:14
366
原创 代码随想录算法训练营第20天|二叉树part7
利用二叉搜索树的特性,二叉搜索树要用中序遍历。235. 二叉搜索树的最近公共祖先。公共祖先一定是满足在两个数中间。701.二叉搜索树中的插入操作。删除二叉搜索树中的节点。上面的代码没有释放内存。
2025-03-10 11:16:17
260
原创 代码随想录算法训练营第十八天|二叉树part6
如果左空 右不空 应该把右返回给上一层。如果右空,左不空,应该把左返回给上一层。530.二叉搜索树的最小绝对差。问题:1.ans数组的更新逻辑。236. 二叉树的最近公共祖先。都不为空的话 就返回当前节点。501.二叉搜索树中的众数。2.pre数组的初始化问题。应该存储所有出现次数等于。
2025-03-08 16:33:20
238
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅