- 博客(54)
- 收藏
- 关注
原创 算法 day 62
一些难的题,思维复杂的题,要注意的细节多的题,让我现在再面对着空白的核心代码模式,我依然是四面漏风。二刷是板上钉钉的事,而我下一步,也许也就是力扣的hot100了,能做到熟练写下的那一天,也许我才有真正回头感慨的资格,看当下,就先赶路吧。以前自己是一个纸上谈兵的人,谈算法色变(指实操环节,至少还是能说得上的),但现在不仅能比较流畅的复写里面很多核心算法的关键代码,还有了一定的举一反三能力,比如自己测验部分大厂的机试题有思路,能做出来一部分,也有力扣的每日一题能独立完成的时候,这个时候都会有不小的成就感。
2025-11-22 23:14:00
305
原创 算法 day 61
在代码中,具体给出的距离还是最经典的欧式距离,也就是两点之间的坐标公式的函数,所以 使用欧拉距离计算 和 广搜搜出来的最短路的节点数是一样的。例如我们再求节点1 到 节点9 的最短距离,用二维数组来表示即:grid[1][9],如果最短距离是10 ,那就是 grid[1][9] = 10。那 节点1 到 节点9 的最短距离 是不是可以由 节点1 到节点5的最短距离 + 节点5到节点9的最短距离组成呢?节点k 到 节点j 的最短距离 也是不经过节点k,中间节点集合为[1...k-1],所以表示为。
2025-11-21 14:58:53
1026
原创 算法 day 60
对所有边松弛一次,相当于计算 起点到达 与起点一条边相连的节点 的最短距离,那么对所有边松弛 k + 1次,就是求 起点到达 与起点k + 1条边相连的节点的 最短距离。但本题有 负权回路,如果松弛 n 次,结果就会有变化了,因为 有负权回路 就是可以无限最短路径(一直绕圈,就可以一直得到无限小的最短距离)。对所有边松弛两次,相当于计算 起点到达 与起点两条边相连的节点的最短距离。在没有负权回路的图中,松弛 n 次以上 ,结果不会有变化。那么每松弛一次,都会更新最短路径,所以结果会一直有变化。
2025-11-20 16:28:09
561
原创 算法 day 59
而且 直接把 边(带权值)加入到 小顶堆(利用堆来自动排序),那么每次我们从 堆顶里 取出 边 自然就是 距离源点最近的节点所在的边。从 边 的角度出发, 在处理 三部曲里的第一步(选源点到哪个节点近且该节点未被访问过)的时候 ,我们可以不用去遍历所有节点了。那么无论图是什么样的,边是什么样的顺序,我们对所有边松弛 n-1 次 就一定能得到 起点到达 终点的最短距离。其实也同时计算出了,起点 到达 所有节点的最短距离,因为所有节点与起点连接的边数最多也就是 n-1 条边。
2025-11-19 14:43:46
481
原创 算法 day 58
因为 minDist表示 节点到最小生成树的最小距离,所以 新节点cur的加入,只需要 使用 grid[cur][j] ,grid[cur][j] 就表示 cur 加入生成树后,生成树到 节点j 的距离。当然拓扑排序也要检测这个有向图 是否有环,即存在循环依赖的情况,因为这种情况是不能做线性排序的。最短路是图论中的经典问题即:给出一个有向图,一个起点,一个终点,问起点到终点的最短路径。先判断入度为0的节点,加入队列中,然后指向的节点入度减一。当年本科毕设,甚至论文里还是这个算法的伪代码。
2025-11-18 11:06:20
490
原创 算法 day 57
理解这一点非常重要,这也是prim算法最核心要点所在,很多录友看不懂prim算法的代码,都是因为没有理解透这个数组的含义。刚刚我有讲过“每次寻找距离最小生成树最近的节点并加入到最小生成树中”,那么如何寻找距离最小生成树最近的节点呢?时间复杂度:nlogn (快排) + logn (并查集) ,所以最后依然是 nlogn。prim算法是从节点的角度采用贪心的策略每次寻找距离最小生成树最近的节点并加入到最小生成树中。在prim算法中,有一个数组特别重要,这里我起名为:minDist。
2025-11-17 22:36:35
462
原创 算法 day 55
,这说明在两条边都可以删除的情况下,要删顺序靠后的边!我们来想一下 有向树的性质,如果是有向树的话,只有根节点入度为0,其他节点入度都为1(因为该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点)。所以情况一:如果我们找到入度为2的点,那么删一条指向该节点的边就行了。但 入度为2 还有一种情况,情况二,只能删特定的一条边,其他部分构成一个有向环,另有一个孤立节点插入环中。情况三: 如果没有入度为2的点,说明 图中有环了(注意是有向环)。对于情况三,删掉构成环的边就可以了。
2025-11-15 17:13:43
1039
原创 算法 day 54 并查集
当我们需要判断两个元素是否在同一个集合里的时候,我们就要想到用并查集。通过模板,我们可以知道,并查集主要有三个功能。用bool类型的题目,现在都觉得眉清目秀了。
2025-11-14 22:36:25
427
原创 算法 day 53
如果该陆地上下左右的空格是有水域,则说明是一条边,陆地的右边空格是水域,则说明找到一条边。如果该陆地上下左右的空格出界了,则说明是一条边,该陆地的下边空格出界了,则说明找到一条边。在搜索的过程中,我们可以枚举,用26个字母替换当前字符串的每一个字符,在看替换后 是否在 strList里出现过,就可以判断 两个字符串 是否是链接的。然后就是求起点和终点的最短路径长度,在无权图中,求最短路,用深搜或者广搜就行,没必要用最短路算法。是一个类似bool的返回值,所以可以说是有向图的入门题了,找好思路并不难。
2025-11-13 13:31:06
788
原创 算法 day 52
第二步:再遍历地图,遍历0的方格(因为要将0变成1),并统计该1(由0变成的1)周边岛屿面积,将其相邻面积相加在一起,遍历所有 0 之后,就可以得出 选一个0变成1 之后的最大面积。这个题其实还是像之前的图论一样,思想很简单,但代码很繁琐,稍不留神就要漏东西导致代码疏忽出错。第一步:一次遍历地图,得出各个岛屿的面积,并做编号记录。这其实就是灵神的“插旗法”,昨天的题单中,光是岛屿数量就可以用插旗来决定dfs是否继续往下进行了。(指的是知道了思想,也要把代码的细节全部注意到的情况)上力扣一看,果然是困难。
2025-11-12 14:40:48
512
原创 算法 day 51
此题需要注意到超时的情况,也就是加入队列的时机。在图论中,一访问到,就要立刻入队。个人觉得,版本二的代码会更好理解一些。在处理边界的时候会更清晰。这个题dfs更好些,给到核心代码模式吧,在力扣上通过的。
2025-11-11 14:50:00
379
原创 算法 day 50
在讲解二叉树章节的时候,其实就已经讲过这两种遍历方式。二叉树的递归遍历,是dfs 在二叉树上的遍历方式。二叉树的层序遍历,是bfs 在二叉树上的遍历方式。dfs 和 bfs 一种搜索算法,可以在不同的数据结构上进行搜索,在二叉树章节里是在二叉树这样的数据结构上搜索。而在图论章节,则是在图(邻接表或邻接矩阵)上进行搜索。void dfs(参数) {if (终止条件) {存放结果;return;for (选择:本节点所连接的其他节点) {处理节点;dfs(图,选择的节点);// 递归。
2025-11-10 18:20:03
686
原创 算法 day 48
如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要跟更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。此时的栈顶元素st.top(),就是凹槽的左边位置,下标为st.top(),对应的高度为height[st.top()](就是图中的高度2)。取栈顶元素,将栈顶元素弹出,这个就是凹槽的底部,也就是中间位置,下标记为mid,对应的高度为height[mid](就是图中的高度1)。当前遍历的元素i,就是凹槽右边的位置,下标为i,对应的高度为height[i](就是图中的高度3)。
2025-11-09 15:35:05
625
原创 算法 day 47 单调栈
正式进入单调栈环节。先学习了单调栈。。时间复杂度为O(n)。例如本题其实就是找找到一个元素右边第一个比自己大的元素,此时就应该想到用单调栈了。那么单调栈的原理是什么呢?为什么时间复杂度是O(n)就可以找到每一个元素的右边第一个比它大的元素位置呢?,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。
2025-11-07 16:11:45
597
原创 算法 day 46
确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组实战中,常常会贪图省事,漏掉最后一步,然后看着wa发呆。每个题有不同的侧重点,可以说步步都很重要吧,以为的捷径,还不如按部就班。p上引用的思维导图,常看常新,虽然代码这东西,照着写上去的一会儿就忘,但是多看几遍,就会成了自己的了。
2025-11-06 15:07:47
515
原创 算法 day 45
这个时候新的 babgag 含有 bag 的数量是在 babga 原本包含的 bag 数量(dp【i - 1】【j】)的基础上,增加了使用新来的 g 新组成的 bag 数量。那最后当然是取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});其实归纳为两个方向,一个是从上到下,一个是从左到右,也就成了 最后的简化形式。
2025-11-05 14:48:02
550
原创 算法 day 44
还是一道最长公共子序列的题目啊,但是要注意递推公式里不再是max,也不需要回退i的那个维度,因为判断的是子数组,是一个包含关系。其实还是一道画图题,要打印dp数组,其实之前也要去理解dp数组的变化顺序。递推公式好出,也很好理解,顺利解决。
2025-11-04 13:17:09
847
原创 算法 day 42
这题不画图真就难度上升一个档次,画图对于理解的帮助可以说不只是一点点。另外,在视频里提到,关于初始化的问题,和什么时候输出dp的哪一个数字,也就是“答案存储在dp数组的哪里”,每个题都需要具体分析。这个和dp初始化数字一样值得考虑和理解,不是一知半解迷迷糊糊就初始0,或者输出二维数组的右下角就完事了。二维数组的右下角,不一定存的是正确答案。一开始想着 这题用双指针或者贪心应该都可以的,也大致思考了一下,明天时间会多一点,会再完善一下这道题的dp,和可能的其他解法。这题不难,看一遍就懂了。
2025-11-03 23:56:55
489
原创 算法 day 40
一进来发现上面大大的已解答,还愣了一下。想起来之前贪心做了,然后看到之后有dp做法,就把解答的数组方法删掉了。这道困难题没有之前那么有压迫感啊,我的评价是不如监控二叉树。消化吸收了能自己敲的级别。甚至不需要dp转移方程,完全自己ac 的一道题。
2025-10-31 13:13:01
302
原创 算法 day 39
有环的打家劫舍1,原来就是分类讨论,一开始的思路是用链表,因为看到环就会想到先判定的那段数学推导(快慢指针)。第一次遇到树形dp。顺便收回之前说监控二叉树那道题是树形dp的言论,原来是树形贪心。这个状态转移方程很简单,过了过了。
2025-10-30 01:49:37
360
原创 算法 day 38
字符串的很多操作都很不熟,这里面也没想到用set,哈希的底子都太弱了。一旦没有那种像本题的完全背包明示,就会很难串联起来之前练过的知识点,说到底来还是熟练度问题,再加上一刷,这都是不可避免的。做好复盘,留下记录,下次再战。感觉好起来了,这道题总算是对完全背包相关的内容熟悉一点了...又回去看了20多分钟的上一道零钱兑换,连带这次的转移方程什么的也明白了。状态转移方程忘记加1了,搞得输出不对,de了半天,找朋友聊完天豁然开朗。(聊的是闲)也许换个思维或者重新开始忘掉之前的思维定势会好很多。
2025-10-29 16:06:37
326
原创 算法 day 37
比上一道题像人类多了,基本能自己a出来,只有一个组合和排列的思考点。就是代码真的不太熟,要看完检查一遍然后修正很多小瑕疵(梦回当时背层序遍历的时候)真的很恶心的一道题,卡了很久用例最后出在整数类型上,而且背包的转化虽然比上一道题好一些,实际上也容易在实操的时候忽略掉和01背包有区别的小细节。和上一题差不多,不再赘述。
2025-10-29 01:37:45
244
原创 算法 day 36
和昨天的思想比较像,这个问题实际上是一个背包问题的变种我们要将石头分成两堆,使得两堆的重量尽可能接近dp[j]表示容量为j的背包能装的最大石头重量最后的结果就是总重量减去两倍的最大接近重量(即两堆石头的重量差)public:int sum=0;
2025-10-27 21:01:00
294
原创 算法 day 34
每一个单元格都是当前背包容量下的最优解 2。对于一个背包先看他能不能放下当前的物体,不能放下就不放(但是得放之前求得的当前背包容量下的最优解(总不可能荣包空着吧),这一格的头上那一个) 3。如果当前面背包可以放下当前物品,就把这个东西放进去,但是只放这个东西的话包可能还有空间。就把包的容量减去当前物品的重量,得到包还剩下多少空间,然后去上一行查这个空间可以放多少东西。其他部分可以画一个二维数组理解它的初始化:左上角是满的,就可以让递推这个过程从左上角任意一个最划算的元素转移过来。
2025-10-26 14:15:50
207
原创 算法 day 33
总觉得dp的递推公式是在两个里面取最大值,也就是dp【i】和dp【i-j】*j,但是忘了还可以直接是(i-j)*j。这道题更能让我深刻一些的体会到,其实dp更吃的是思维量和一种系统化的解题顺序,反而不太能体现在直接的代码中。要计算dpn, 就需要挨个把1~n的n个节点作为根节点,然后统计左右子树的乘积(在这个位置才重新用到了dp数组)。用动态规划做的,一般都陷入 n和n-1是什么关系,这种线性思考的死路上去了(这道题是非线性的)这个题就难一些了,在递推的时候想了太多,但是好在看题解的时候理解也很快。
2025-10-25 00:57:36
284
原创 算法 day 31
i=1: 比较 '3'和'2' → 3>2,违反规则。i=1: 比较 '1'和'0' → 1>0,违反规则。i=2: 比较 '2'和'3' → 2<3,通过。i=2: 比较 '3'和'2' → 3>2,违反规则。设置 flag=2,将第一个'3'减1变成'2'设置 flag=1,将第一个'3'减1变成'2'设置 flag=1,将 '1'减1变成'0'i=3: 比较 '3'和'4' → 3<4,通过。i=1: 比较 '1'和'2' → 1<2,通过。将flag(1)后所有位设为9: "299"
2025-10-22 18:00:22
314
原创 算法 day 30
完全知道怎么做,但是用代码实现不出来的一道题...字符串这一块的底子太差了,居然没想到用hash来装。就统计最后一个字母出现的位置这一行,就得看了以后才能恍然大悟。hash[S[i] - 'a'这个表示的就是i位置上字母出现的下标,最后用一个max表达式就ok了。首先排序区间,然后再按照左区间对齐。其实挺像昨天的最后一题的。注意更新最近的右区间的时候,取得的是共同最小值,而不是最大值。和上一题很像的一道题,所以就还是用左区间对齐做了。
2025-10-21 23:12:06
140
原创 算法 day 29
不过确实有想法和有全面的思路是两回事,没想出来。把视频看一遍,自己操刀,就能写出来了,和自己想的差距有,但是确实没有顾及到从右往左遍历的时候是从数组的后面开始的,一开始就一直角落上的答案不对,改数据又会爆栈,难受。另外也学习到了vector的一些底层机制,他的insert操作很费事费时,如果可以要多用std 的list来节省时间,可能会避免超时。按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。有难度的一道题,也是两个维度考虑。
2025-10-20 20:38:42
157
原创 算法 day 27
这个思路其实也还好,因为是一个bool值,所以我的思路是如果最后一步能到,那么就看倒数第二步能不能顺利到最后一步。以此类推,就到了覆盖范围这一个概念,也就是说,只要n-1步能覆盖到最后一步,函数就返回true。确实很直觉的一道题,把绝对值先排序,然后负数大的先反转,负数全处理掉,就反复反转最小的正数。我没做出来是因为我差了一点意思,又按顺序去反转正数,这就导致了可能第二小第三小的正数也被反转掉的。每一天的差值是一个单元,所以只保留正数的插值,代表买卖可以赚钱,负数的差值就不需要。这个就没想出来了,看思路。
2025-10-19 15:25:39
166
原创 算法 day 26
今天进入了贪心环节。其实在进入贪心之前,会有一些感想。不过自己离独立完成一场机试还有一定距离,先放下所有杂念让自己好好成长吧。
2025-10-17 22:58:41
284
原创 算法 day 24
上强度了,依旧流汗。说实话,这题连isValid这个函数都不算好写。另外,这题要额外注意一下insert的位置和i+2这两个点。加了一个去重的子集1问题。真得多看看回溯第八题,回溯最老实的一道题,居然还可以不加终止条件。
2025-10-16 00:00:07
151
原创 算法 day 23
对于这个题来说,最大的区别是原来的数据源集合里面出现了重复的数据。因此 ,这道题的难点就在于两个去重:第一,保证原来的集合中的元素只被使用一次;第二,解集的元素也不能重复出现,这就导致元素和集合都不能重复。感觉hard的一道题,冒汗了。甚至还犯了substr的低级错误,花了一个多小时在完全知道思路的情况下才把代码敲出来。对于这个题来说,传参的个数,什么时候传什么参,往往比回溯的这个思想过程更复杂,回溯过程只要按模板写就ok了。1.递归的结束条件为切割结束,也就是startIndex到了字符串末尾的位置。
2025-10-14 12:46:44
300
原创 算法 day 22
这题就更难受了,完全没有二叉树环节中的得心应手思想的感觉,思想理解都花了一点时间。每道题基本都是想到超时然后再看题解,只能说之前练的实在是太少了,抓紧补补吧..不过在视频评论区看到一句很有用的话:总结:对于回溯算法的树,深度决定了什么时候递归return,宽度决定了每一层递归要回溯的次数。慢慢理解回溯和递归的奥秘中。
2025-10-13 14:51:10
169
原创 算法 day 20
不过自己修为也不够,这个没a出来,要看下题解,需要多多复习这一块。总体来说,感觉二叉树前面半部分可能花的时间更多一些,后半部分就有点求快,题目上难度了反而做题和理解的质量,深度都有所下降,一个也确实最近学业,求职都有些忙,客观上来说尽量不要懈怠,保质保量,所有的题目都是实操写出来代码远大于理解思想,对自己一刷的题要求高些,后面复习也会舒服些。这个题整体不难,但是要注意,left和right都要能接住上一行对应的递归。和构建一个二叉树类似的递归思想,数组化成树节点就比较自然了。
2025-10-10 23:48:39
131
原创 算法 day 19
和上一题的友好截然不同,crud里面本是同根生,结果差别这么大。实打实的没做出来而且没什么思路,老老实实跟着敲一遍,标记重点好了。核心其实就一句话:当我们从上向下去递归遍历,第一次遇到 cur节点是数值在[q, p]区间中,那么cur就是 q和p的最近公共祖先。
2025-10-09 23:53:55
229
原创 算法 day 18
于是想了想pre和cur 的指针进程,在一些细节上会抠错。据了解,字节,美团,蚂蚁,今年全都考过这道题。同时也又复习了一遍pre和cur指针的写法,这个和链表的思维模式确实不一样哈。3.count并非一个单一的元素,因为真正的众数是maxcount,count本质上只是一个计数器。反之亦然,最后返回的根节点就是最近的公共祖先了。2.众数的count不是只加不减的,每次下一个元素和当前的不一样,count马上就要回到1;这道题在看了思路以后自己进行了尝试,修修补补算是半个自己做出来了。
2025-10-09 01:00:43
331
原创 算法 day 17
第一次做,就是用新数组的冗余代码(方案一)做的。这样的思想比较自然,今天主要就又看了一遍,看到了不操作多余空间的写法。但是在递归中,这个题的代码相当于一次中左右,中只需要确定一个节点,即当前的根节点,不处理左右子树的节点,因为左右子树的节点也会在之后的递归中变成那一次的根节点。学习到了二叉搜索树的中序遍历是一个有序数组,所以变成了一个数组操作。此外,要注意的坑是:如果直接在树上操作,这个当前节点不是仅仅大于左节点,小于右节点。而是大于和小于整个子树。因为返回的值类型是树节点,所以找到值的时候立刻返回即可。
2025-10-08 12:25:15
151
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅