自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(49)
  • 收藏
  • 关注

原创 代码随想录Day57:图论(寻宝prim算法精讲&kruskal算法精讲)

prim算法精讲所有节点的最小连通子图,即:以最小的成本(边的权值)将图中所有节点链接到一起。图中有n个节点,那么一定可以用n-1条边将所有节点连接到一起。从节点的角度采用贪心的策略每次寻找距离最小生成树最近的节点并加入到最小生成树中。。第一步,选距离生成树最近节点。第二步,最近节点加入生成树。第三步,更新非生成树节点到生成树的距离(即更新minDist数组。minDist数组用来记录每一个节点距离最小生成树的最近距离。注意:下标0不用管,下标1与节点1对应,这样可以避免把节点搞混。

2025-08-20 16:50:17 893

原创 代码随想录Day56:图论(冗余连接、冗余连接II)

本质是一个有向图,是由一颗有向树 + 一条有向边组成的 (所以此时这个图就不能称之为有向树),现在让我们找到那条边 把这条边删了,让这个图恢复为有向树。思路:本题需要注意的是在本来就构成树的基础上,添加一条边(依然是n个节点,但有n条边),使这个图变成了有环图,那我们寻找冗余的边,那必然就只有。有向树的性质:只有根节点入度为0,其他节点入度都为1(因为该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点)。如果我们找到入度为2的点,那么删一条指向该节点的边就行了。

2025-08-19 17:49:41 468

原创 代码随想录Day55:图论(并查集理论基础、寻找存在的路径)

并查集理论基础并查集主要两个功能(代码层面,如何将两个元素添加到同一个集合中呢?可以放到同一个数组里或者set 或者 map 中,这样就表述两个元素在同一个集合。将三个元素A,B,C (分别是数字)放在同一个集合,其实就是将三个元素连通在一起,如何连通呢。只需要用一个一维数组来表示,即:father[A] = B,father[B] = C 这样就表述 A 与 B 与 C连通了(有向连通图)。那怎么知道 B 连通 A呢?判断这几个元素是否在同一个集合,寻根思路。

2025-08-18 17:06:46 819

原创 代码随想录Day53:图论(岛屿的周长、字符串接龙、有向图的完全可达性)

岛屿的周长思路1:本题不需要使用BFS或者DFS,但是在过程中需要类似的思考。遍历每一个空格,遇到岛屿则计算其上下左右的空格情况:1.如果该陆地上下左右的空格是,则说明是一条边2.如果该陆地上下左右的空格,则说明是一条边思路2:计算出总的岛屿数量,总的变数为:岛屿数量 * 4。因为有一对相邻两个陆地,边的总数就要减2,如图红线部分,有两个陆地相邻,总边数就要减2。那么只需要在计算出相邻岛屿的数量就可以了,相邻岛屿数量为cover。结果 result = 岛屿数量 * 4 - cover * 2;

2025-08-17 22:21:03 1162

原创 代码随想录Day52:图论(孤岛的总面积、沉没孤岛、水流问题、建造最大岛屿)

每改变一个0的方格,都需要重新计算一个地图的最大面积,所以 整体时间复杂度为:n^4,复杂度很高,会超时。思路可以完全一样,从地图周边出发,将周边空格相邻的陆地都做上标记,然后在遍历一遍地图,遇到 陆地 且没做过标记的,那么都是地图中间的 陆地 ,全部改成水域就行。第二步:再遍历地图,遍历0的方格(因为要将0变成1),并统计该1(由0变成的1)周边岛屿面积,将其相邻面积相加在一起,遍历所有 0 之后,就可以得出 选一个0变成1 之后的最大面积。第一步:一次遍历地图,得出各个岛屿的面积,并做编号记录。

2025-08-16 16:46:19 1164

原创 代码随想录Day51:图论(岛屿数量 深搜&广搜、岛屿的最大面积)

思路是用遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。在遇到标记过的陆地节点和海洋节点的时候直接跳过。思路:如果是有结束条件版本,dfs处理当前节点,即在主函数遇到岛屿就计数为0,dfs处理接下来的全部陆地;如果是无结束条件版本,则dfs处理当前节点的相邻节点,即在主函数遇到岛屿就计数为1,dfs处理接下来的相邻陆地。本题思路与深搜类似,遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。岛屿的最大面积(深搜-无结束条件版本)

2025-08-15 21:32:01 473

原创 代码随想录Day50:图论(图论理论、深度搜索理论、所有可达路径、广度搜索理论)

1.1图的种类:整体上一般分为和。此外还有加权有向/无向图1.2度:无向图中有几条边连接该节点,该节点就有几度。在有向图中,每个节点有出度和入度。出度:从该节点出发的边的个数。入度:指向该节点边的个数。1.3连通性:在图中表示节点的连通情况,我们称之为连通性。无向图中,任何两个节点都是可以到达的,我们称之为如果有节点不能到达其他节点,则为非连通图在有向图中,任何两个节点是可以相互到达的,我们称之为。在无向图中的极大连通子图称之为该图的一个。在有向图中极大强连通子图称之为该图的。

2025-08-14 22:44:29 986

原创 代码随想录Day49:单调栈(接雨水、柱状图中最大的矩形)

如果数组本身是降序的,例如 [8,6,4,2],在 8 入栈后,6 开始与8 进行比较,此时我们得到 mid(8),right(6),但是得不到 left。从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。如果数组本身就是升序的,例如[2,4,6,8],那么入栈之后 都是单调递减,一直都没有走 情况三 计算结果的哪一步,所以最后输出的就是0了。

2025-08-13 18:03:47 1055

原创 代码随想录Day48:单调栈(每日温度、下一个更大元素 I、下一个更大元素II)

使用场景。时间复杂度:O(n)本质,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。遍历数组的时候,不知道之前都遍历了哪些元素,以至于遍历一个元素找不到是不是之前遍历过一个更小的,所以我们需要用一个容器(这里用单调栈)来记录我们遍历过的元素。使用单调栈注意点。

2025-08-12 21:05:38 653

原创 代码随想录Day46:动态规划(回文子串、最长回文子序列、动态规划总结)

确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组关于动态规划,你该了解这些!动态规划:斐波那契数(opens new window)动态规划:爬楼梯(opens new window)动态规划:使用最小花费爬楼梯(opens new window)动态规划:不同路径(opens new window)动态规划:不同路径还不够,要有障碍!动态规划:整数拆分,你要怎么拆?动态规划:不同的二叉搜索树(opens new window)

2025-08-11 14:39:51 914

原创 代码随想录Day45:动态规划(不同的子序列、两个字符串的删除操作、编辑距离)

也就是 dp[i - 1][j - 1]。那最后当然是取最小值,所以当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});if (word1[i - 1] == word2[j - 1]) 那么说明不用任何编辑,dp[i][j] 就应该是 dp[i - 1][j - 1],即dp[i][j] = dp[i - 1][j - 1];

2025-08-10 22:39:41 983

原创 代码随想录Day44:动态规划(最长公共子序列、不相交的线、最大子序和、判断子序列)

t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。同理dp[0][j]也是0。

2025-08-09 23:01:20 1110

原创 代码随想录Day43:动态规划(最长递增子序列、最长连续递增序列、最长重复子数组)

如果定义 dp[i][j]为 以下标i为结尾的A,和以下标j 为结尾的B,那么 第一行和第一列毕竟要进行初始化,如果nums1[i] 与 nums2[0] 相同的话,对应的 dp[i][0]就要初始为1, 因为此时最长重复子数组为1。但dp[i][0] 和dp[0][j]要初始值,因为 为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1;即当A[i - 1] 和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1;的子序列长度为dp[i]。

2025-08-08 17:49:48 1152

原创 代码随想录Day42:动态规划(买卖股票的最佳时机IV、最佳买卖股票时机含冷冻期、买卖股票的最佳时机含手续费)

今天卖出了股票(状态三),同上分析,dp[0][2]初始化为0,dp[0][3]也初始为0。那么dp[i][0] = max(dp[i - 1][0], dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]);选最大的,所以 dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);所以dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])

2025-08-07 18:44:18 1131

原创 代码随想录Day41:动态规划(买卖股票的最佳时机、买卖股票的最佳时机II、买卖股票的最佳时机III)

同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);那么dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);一定是选最大的,所以 dp[i][1] = max(dp[i-1][0] - prices[i], dp[i - 1][1]);那么dp[i][1]究竟选 dp[i-1][0] - prices[i],还是dp[i - 1][1]呢?

2025-08-06 20:58:54 1059

原创 代码随想录Day39:动态规划(打家劫舍、打家劫舍II、打家劫舍III)

参数为当前节点,返回的就是dp数组,dp数组(dp table)以及下标的含义:下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。第i房间,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。首先明确的是使用后序遍历。),然后dp[i]取最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])

2025-08-05 15:43:57 871

原创 代码随想录Day38:动态规划(零钱兑换、完全平方数、单词拆分)

确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);动态规划:416.分割等和子集(opens new window)动态规划:1049.最后一块石头的重量 II(opens new window)动态规划:494.目标和(opens new window)

2025-08-04 18:10:56 972

原创 代码随想录Day37:动态规划(完全背包理论、零钱兑换 II、组合总和 Ⅳ、爬楼梯)

动态规划的状态 `dp[j]` 表示:凑成金额 `j` 的方法数。---1. 外层遍历物品,内层遍历背包容量 → 求组合数```javai++) { // 遍历物品j++) { // 遍历背包容量```如何理解“组合数”?这种遍历顺序的本质是:我们是按“物品的种类”来分组考虑的。想象一下这个过程:1. **第一轮 (i=0, coins[0]=1)**:* 我们只考虑使用 **1元硬币**。

2025-08-03 12:55:53 1286

原创 代码随想录Day36:动态规划(最后一块石头的重量 II、目标和、一和零)

1049最后一块石头的重量 II思路:本题实质上和上一题类似,尽量让石头分成重量相同的两堆(尽可能相同),相撞之后剩下的石头就是最小的。一堆的石头重量是sum,那么我们就尽可能拼成 重量为 sum / 2 的石头堆。这样剩下的石头堆也是 尽可能接近 sum/2 的重量。那么此时问题就是有一堆石头,每个石头都有自己的重量,是否可以 装满 最大重量为 sum / 2的背包。转化成。

2025-08-02 17:06:12 1127

原创 代码随想录Day35:动态规划(背包问题 二维 一维、分割等和子集)

背包空出物品i的容量后,背包容量为j - weight[i],dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]且不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值。递归公式中可以看出dp[i][j]是靠dp[i-1][j]和dp[i - 1][j - weight[i]]推导出来的。时,dp[0][j] 应该是value[0],因为背包容量放足够放编号0物品。

2025-07-31 23:18:34 1330

原创 代码随想录Day34:动态规划(不同路径、不同路径 II、整数拆分、不同的二叉搜索树)

当1为头结点的时候,其右子树有两个节点,看这两个节点的布局,是不是和 n 为2的时候两棵树的布局是一样的。(不用关心其具体数值的差异)当3为头结点的时候,其左子树有两个节点,看这两个节点的布局,是不是和n为2的时候两棵树的布局也是一样的啊!dp[3],就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量。所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2],如图所示。有1个元素的搜索树数量就是dp[1]。

2025-07-29 23:21:12 580

原创 代码随想录Day32:动态规划(斐波那契数、爬楼梯、使用最小花费爬楼梯)

什么是动态规划(Dynamic Programming)?如果某一问题有很多重叠子问题,使用动态规划是最有效的。动态规划中每一个状态一定是由上一个状态推导出来的,,贪心没有状态推导,而是从局部直接选最优的,而且很多讲解动态规划的文章都会讲最优子结构啊和重叠子问题啊这些,这些东西都是教科书的上定义,晦涩难懂而且不实用,。误区:状态转移公式(递推公式)只是一部分,必须掌握根本性的解题步骤。确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序。

2025-07-28 23:31:05 914

原创 代码随想录Day31:贪心算法(合并区间、单调递增的数字、监控二叉树 )

以下三道题目就是简单题,会发现贪心感觉就是常识。贪心算法:分发饼干(opens new window)贪心算法:K次取反后最大化的数组和(opens new window)贪心算法:柠檬水找零(opens new window)

2025-07-26 21:28:32 867

原创 代码随想录Day30:贪心算法(用最少数量的箭引爆气球、无重叠区间、划分字母区间)

如果不重叠,那就不需要做任何操作,如果区间重叠,则增加重叠区域个数result,此外还需要更新右边界为两个重叠区间中最小值,因为只有更小的右区间才有更大的可能和下一个区间不重叠,并且我们这里并不要求给出具体要被删除的重叠区间,所以不会有影响。如果把气球排序之后,从前到后遍历气球,被射过的气球仅仅跳过就行了,没有必要让气球数组remove气球,只要记录一下箭的数量就可以了。可以看出首先第一组重叠气球,一定是需要一个箭,气球3,的左边界大于了 第一组重叠气球的最小右边界,所以再需要一支箭来射气球3了。

2025-07-25 23:07:09 714

原创 代码随想录Day29:贪心算法(加油站、分发糖果、柠檬水找零、根据身高重建队列)

i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。注意:result不需要用%,我的理解是一开始出发点就设置在0,一般来说出发点一圈回出发点,分为两个区间,一般都是区间1大于等于0,区间2小于等于0,所以一旦curSum小于0,就可以将前面的区间默认区间2,后面是区间1,那出发点很明显就是i+1,按这个现象,我们会发现无需使用%。

2025-07-24 21:27:07 958

原创 代码随想录Day28:贪心算法(买卖股票的最佳时机II、跳跃游戏、跳跃游戏II、K次取反后最大化的数组和)

假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0],相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0]),大家自己加一下每一天的利润,确实是和整体角度是一样的,并且买卖股票并不一定要求连续,所以我们判断每一天利润,大于0则使用,否则就不用,也就是当做这天利润为0,因为如果使用负数利润就是拖后腿。这个范围内,别管是怎么跳的,反正一定可以跳过来。

2025-07-23 23:28:58 1176

原创 代码随想录Day27:贪心算法(分发饼干、摆动序列、最大子序和)

举一个例子:例如,有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿?指定每次拿最大的,最终结果就是拿走最大数额的钱。每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优。

2025-07-22 23:47:27 1068

原创 代码随想录Day25:回溯算法(递增子序列、全排列、全排列 II)

1.回溯是递归的副产品,只要有递归就会有回溯,所以回溯法也经常和二叉树遍历,深度优先搜索混在一起,因为这两种方式都是用了递归。组合问题:N个数里面按一定规则找出k个数的集合排列问题:N个数按一定规则全排列,有几种排列方式切割问题:一个字符串按一定规则有几种切割方式子集问题:一个N个数的集合里有多少符合条件的子集棋盘问题:N皇后,解数独等等(之后单独开一个文章)

2025-07-21 23:03:53 959

原创 代码随想录Day24:回溯算法(复原IP地址、子集、子集II)

其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。既然是无序,取过的元素不会重复取,写回溯算法的时候,for就要从startIndex开始,而不是从0开始!从图中红线部分,可以看出遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合。区别就是集合里有重复元素了,而且求取的子集要去重。所以我们同样可以使用used数组先排序,之后去重,用used判断是同一层进行去重,枝干中不误去。思路:如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,

2025-07-19 17:56:07 488

原创 代码随想录Day23:回溯算法(组合总和、组合总和II、分割回文串)

如果candidates[i] == candidates[i - 1] 并且 used[i - 1] == false,就说明:前一个树枝,使用了candidates[i - 1],也就是说同一树层使用过candidates[i - 1],此时for循环里就应该做continue的操作。注意图中叶子节点的返回条件,因为本题没有组合数量要求,仅仅是总和的限制,所以递归没有层数的限制,只要选取的元素总和超过target,就返回!题目元素在同一个组合内是可以重复的,怎么重复都没事,但两个组合不能相同。

2025-07-17 18:20:25 1192

原创 代码随想录Day22:回溯算法(组合与优化、组合总和III、电话号码的字母组合)

回溯与递归相辅相成,一般用在递归函数下面。回溯是纯暴力搜索的方法,回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案,效率不高。

2025-07-16 22:21:38 1177

原创 代码随想录Day21:二叉树(修剪二叉搜索树、将有序数组转换为二叉搜索树、把二叉搜索树转换为累加树——全递归版本以及总结)

关于二叉树的属性二叉树:是否对称(opens new window)递归:后序,比较的是根节点的左子树与右子树是不是相互翻转二叉树:求最大深度(opens new window)递归:后序,求根节点最大高度就是最大深度,通过递归函数的返回值做计算树的高度二叉树:求最小深度(opens new window)递归:后序,求根节点最小高度就是最小深度,注意最小深度的定义二叉树:求有多少个节点(opens new window)递归:后序,通过递归函数的返回值计算节点数量。

2025-07-15 18:09:52 1057

原创 代码随想录Day20:二叉树(二叉搜索树的最近公共祖先、二叉搜索树中的插入操作、删除二叉搜索树中的节点——全递归版本)

参数就是根节点指针,以及要插入元素,这里递归函数可以有返回值,也可以没有,但递归函数如果没有返回值的话,实现是比较麻烦的,下面也会给出其具体实现代码。4.要删除的节点是两边都不空,在不改变左右分支的结构的前提下合在一起,将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。思路:与之前的二叉树的最近公共祖先不同的是,本题的背景是二叉搜索树。3.确定单层递归的逻辑。

2025-07-14 22:22:06 1175

原创 代码随想录Day18:二叉树(二叉搜索树的最小绝对差、二叉搜索树中的众数、二叉树的最近公共祖先——全递归版本)

示例 2: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。示例 1: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。既然是搜索树,它中序遍历就是有序的。给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

2025-07-14 20:58:06 806

原创 代码随想录Day17:二叉树(最大二叉树、合并二叉树、二叉搜索树中的搜索、验证二叉搜索树——全递归版本)

题目中说了输入的数组大小一定是大于等于1的,不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了。2.确定递归函数的参数和返回值:参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。其实和遍历一个树逻辑是一样的,只不过。

2025-07-12 21:17:23 852

原创 代码随想录Day16:二叉树(找树左下角的值、路径总和、从中序与后序遍历序列构造二叉树——全递归版本)

因为前序(根左右)和后序(左右根)能定义根的位置,但无法判断左右区间。

2025-07-11 21:11:33 1316

原创 代码随想录Day15:二叉树(平衡二叉树、二叉树的所有路径、左叶子之和、完全二叉树的节点个数——全递归版本)

此时还没完,递归完,要做回溯啊,因为path 不能一直加入节点,它还要删节点,然后才能加入新的节点。我们知道,回溯和递归是一一对应的,有一个递归,就要有一个回溯,这么写的话相当于把递归和回溯拆开了, 一个在花括号里,一个在花括号外。如果当前节点是叶子节点(没有左孩子和右孩子的节点),那么它的左右递归调用将直接因为检测到null而返回,不会进行更多的处理。如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子。返回值:以当前传入节点为根节点的树的高度。

2025-07-09 21:35:43 1265

原创 代码随想录Day14:二叉树(翻转二叉树、对称二叉树、二叉树的最大深度、二叉树的最小深度——全递归版本)

思路:其实就是交换每一个节点的左右孩子。按顺序遍历所有节点之后进行左右孩子交换递归方法有一个注意点,就是中序遍历不行,前序后序都可以。为什么中序不行?本质原因是前后序的根节点都在边上,我们做节点交换处理就是在根节点上处理。但是中序遍历试想一下,前把左子树各种交换完成之后,然后根节点交换左右子树,此时之前的左子树变成右子树,然后对右子树进行,那就不对了、

2025-07-08 22:59:39 1325

原创 代码随想录Day13:二叉树(递归遍历、迭代遍历、统一迭代、层序遍历)

顺序存储就是用数组来存,这个定义没啥可说的,我们来看看链式存储的二叉树节点的定义方式。int val;相对于链表 ,二叉树的节点里多了一个指针, 有两个指针,指向左右孩子。

2025-07-08 17:51:48 697

原创 代码随想录Day11:栈与队列(逆波兰表达式求值、滑动窗口最大值、前 K 个高频元素)

栈与队列是我们熟悉的不能再熟悉的数据结构,但它们的底层实现就是基础所在。可以出一道面试题:栈里面的元素在内存中是连续分布的么?陷阱1:栈是容器适配器,底层容器使用不同的容器,导致栈内数据在内存中不一定是连续分布的。陷阱2:缺省情况下,默认底层容器是deque,那么deque在内存中的数据分布是什么样的呢?答案是:不连续的,下文也会提到deque。括号匹配先来分析一下 这里有三种不匹配的情况,第一种情况,字符串里左方向的括号多余了,所以不匹配。第二种情况,括号没有多余,但是括号的类型没有匹配上。

2025-07-05 22:54:20 843

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除