- 博客(45)
- 收藏
- 关注
原创 力扣 617-合并二叉树
因为是传入了两个树,那么就有两个树遍历的节点root1 和 root2,如果root1 == NULL 了,两个树合并就应该是 root2 了(如果root2也为NULL也无所谓,合并之后就是NULL)。反过来如果root2 == NULL,那么两个数合并就是root1(如果root1也为NULL也无所谓,合并之后就是NULL)。单层递归的逻辑就比较好写了,这里我们重复利用一下root1这个树,root1就是合并之后树的根节点(就是修改了原来树的结构)。最终root1就是合并之后的根节点。
2024-03-12 08:59:32
413
1
原创 力扣-[700. 二叉搜索树中的搜索]
如果root.val > val,搜索左子树,如果root.val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。递归法 确定递归函数的参数和返回值 递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。而对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。
2024-03-12 08:58:30
461
原创 力扣每日一题day39[105. 从前序与中序遍历序列构造二叉树]
思路 根据两个顺序构造一个唯一的二叉树,以 后先序数组的第一个元素为切割点,先切中序数组,根据中序数组,反过来在切先序数组。中序数组我们都切成了左中序数组和右中序数组了,那么先序数组就可以按照左中序数组的大小来切割,切成左先序数组和右先序数组。先序数组没有明确的切割元素来进行左右切割,不像中序数组有明确的切割点,切割点左右分开就可以了。第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)切割点在先序数组的第一个元素,就是用这个元素来切割中序数组的,所以必要先切割中序数组。
2023-12-30 21:56:01
481
原创 算法分析与设计基础
算法分析指对算法所需要的两种计算机资源:时间和空间进行评估。算法所需要的资源越少,算法效率越高。一个函数的增长率是指当输入规模增大的时候,该函数的值增长得有多快。对算法分析有重要意义的函数值显然函数 x^3 比函数 x^2 要增长得快;如果算法 A 对于输入规模x需要 x^3 个操作,算法 B 需要 x^2 个操作, 算法 B 更高效;因为函数的增长率, 我们会把函数x^3 + x^2 + x 等同于x^3。匹配成功最好:TB(n, m) = m∈Ω(m)
2023-12-29 22:23:11
2098
原创 力扣每日一题day38[106. 从中序与后序遍历序列构造二叉树]
思路 根据两个顺序构造一个唯一的二叉树,以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来在切后序数组。中序数组我们都切成了左中序数组和右中序数组了,那么后序数组就可以按照左中序数组的大小来切割,切成左后序数组和右后序数组。后序数组没有明确的切割元素来进行左右切割,不像中序数组有明确的切割点,切割点左右分开就可以了。切割点在后序数组的最后一个元素,就是用这个元素来切割中序数组的,所以必要先切割中序数组。第五步:切割后序数组,切成后序左数组和后序右数组。后序数组的切割点怎么找?
2023-12-23 00:57:52
408
原创 力扣每日一题day36[112.路径总和]
给你二叉树的根节点root和一个表示目标和的整数targetSum。判断该树中是否存在的路径,这条路径上所有节点值相加等于目标和targetSum。如果存在,返回true;否则,返回false。是指没有子节点的节点。true等于目标和的根节点到叶节点路径如上图所示。false树中存在两条根节点到叶子节点的路径:(1 --> 2): 和为 3(1 --> 3): 和为 4不存在 sum = 5 的根节点到叶子节点的路径。false由于树是空的,所以不存在根节点到叶子节点的路径。
2023-12-21 23:19:47
1442
原创 力扣每日一题day34[110. 平衡二叉树]
关于根节点的深度究竟是1 还是 0,不同的地方有不一样的标准,leetcode的题目中都是以节点为一度,即根节点深度是1。分别求出其左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则返回-1,表示已经不是二叉平衡树了。递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0。参数:当前传入节点。返回值:以当前传入节点为根节点的树的高度。二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。
2023-12-12 12:49:28
393
原创 力扣每日一题day33[111. 二叉树的最小深度]
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数后者节点数(取决于高度从0开始还是从1开始)用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)本题依然是前序遍历和后序遍历都可以,前序求的是深度,后序求的是高度。如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。参数为要传入的二叉树根节点,返回的是int类型的深度。
2023-12-10 21:33:40
469
原创 力扣每日一题day32[104. 二叉树的最大深度]
给定一个二叉树root,返回其最大深度。二叉树的是指从根节点到最远叶子节点的最长路径上的节点数。32。
2023-12-10 21:30:22
430
原创 力扣每日一题day31[101. 对称二叉树]
比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。, 检查它是否轴对称。
2023-12-08 22:29:14
1602
原创 力扣每日一题day30[226. 翻转二叉树]
这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次。遍历的过程中去翻转每一个节点的左右孩子就可以达到整体翻转的效果。注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果。只要把每一个节点的左右孩子翻转一下的遍历方式都是可以的!关键在于遍历顺序,前中后序应该选哪一种遍历顺序?把每一个节点的左右孩子交换一下就可以了。,翻转这棵二叉树,并返回其根节点。给你一棵二叉树的根节点。
2023-12-07 22:17:00
416
原创 力扣每日一题day29[102. 二叉树的层序遍历]
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。(即逐层地,从左到右访问所有节点)。而这种层序遍历方式就是图论中的广度优先遍历。使用队列实现二叉树广度优先遍历。
2023-12-07 22:13:46
437
原创 力扣每日一题day28 [94. 二叉树的中序遍历][144. 二叉树的后序遍历][145. 二叉树的后序遍历]
处理:将元素放进result数组中 访问:遍历节点 分析一下为什么刚刚写的前序遍历的代码,不能和中序遍历通用,因为前序遍历的顺序是中左右,先访问的元素是中间节点,要处理的元素也是中间节点,所以刚刚才能写出相对简洁的代码,因为要访问的元素和要处理的元素顺序是一致的,都是中间节点。中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的。因为这样出栈的时候才是中左右的顺序。
2023-12-05 23:43:29
602
原创 力扣每日一题day26[42. 接雨水]
按照列方向计算,只要记录左边柱子的最高高度和右边柱子的最高高度,就可以计算出当前位置雨水的面积;当前位置的雨水面积=[min(左边柱子的最高高度,右边柱子的最高高度)-当前柱子高度]x1。上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。使用双指针来遍历,每到一个柱子都向两边遍历一遍,会有重复计算,我们将每个位置左边最高高度记录在一个数组中,右边最高高度记录在一个数组中。个非负整数表示每个宽度为。
2023-12-03 20:43:04
391
原创 力扣每日一题day26[347. 前 K 个高频元素]
对频率进行排序可以使用优先级队列,优先级队列利用堆完成对元素的排序,这里使用小顶堆,因为小顶堆可以每次将最小的元素弹出,最后剩下前k个。统计元素出现次数可以使用map进行统计。,请你返回其中出现频率前。
2023-12-01 23:48:25
387
原创 力扣每日一题day25[239. 滑动窗口最大值]
poll(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作 add(value):如果add的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到add元素的数值小于等于队列入口元素的数值为止 保持如上规则,每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。此时我们需要一个队列,这个队列,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。
2023-11-30 23:42:36
402
原创 力扣每日一题day24[150. 逆波兰表达式求值]
但是不必从二叉树的角度解决问题,只需要知道逆波兰表达式是用后序遍历的方式把二叉树序列化就可以了。以["4","13","5","/","+"]为例,当遍历到”/“时,就处理”13“,”5“,”/“这道题每一个子表达式要得出一个结果,然后拿这个结果再进行运算,就是一个相邻字符串消除的过程。该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6。该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9。继续遍历,当遇到“+”时就处理“4”,“2”,“+”得到结果6。
2023-11-29 23:39:01
839
原创 力扣每日一题day23[20. 有效的括号]
第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false。第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false。第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。第一种情况,字符串里左方向的括号多余了 ,所以不匹配。第二种情况,括号没有多余,但是 括号的类型没有匹配上。第三种情况,字符串里右方向的括号多余了,所以不匹配。字符串遍历完之后,栈是空的,就说明全都匹配了。
2023-11-28 10:52:35
389
原创 力扣每日一题day22[225. 用队列实现栈]
队列是先进先出的规则,把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并没有变成先进后出的顺序。但是依然还是要用两个队列来模拟栈,只不过没有输入和输出的关系,而是另一个队列完全用又来备份的!所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(myStack.empty();// 返回 False。
2023-11-27 10:57:37
387
原创 力扣每日一题day21[232. 用栈实现队列]
在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。请你仅使用两个栈实现先入先出队列。这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。
2023-11-26 15:43:15
369
原创 力扣每日一题day20[459. 重复的子字符串]
步骤一:因为 这是相等的前缀和后缀,t[0] 与 k[0]相同, t[1] 与 k[1]相同,所以 s[0] 一定和 s[2]相同,s[1] 一定和 s[3]相同,即:,s[0]s[1]与s[2]s[3]相同。步骤三: 因为 这是相等的前缀和后缀,t[2] 与 k[2]相同 ,t[3]与k[3] 相同,所以,s[2]一定和s[4]相同,s[3]一定和s[5]相同,即:s[2]s[3] 与 s[4]s[5]相同。= 0,则说明字符串有最长相同的前后缀(就是字符串里的前缀子串和后缀子串相同的最长长度)。
2023-11-24 23:13:05
368
原创 力扣每日一题day19[28. 找出字符串中第一个匹配项的下标]
给你两个字符串 和 ,请你在 字符串中找出 字符串的第一个匹配项的下标(下标从 0 开始)。如果 不是 的一部分,则返回 。示例 1:输入:haystack = "sadbutsad", needle = "sad"输出:0解释:"sad" 在下标 0 和 6 处匹配。第一个匹配项的下标是 0 ,所以返回 0 。示例 2:输入:haystack = "leetcode", needle = "leeto"输出:-1解释:"leeto" 没有在 "leetcode" 中出现
2023-11-23 23:54:06
873
原创 力扣每日一题day18[151. 反转字符串中的单词]
移除多余空格 : "the sky is blue" 字符串反转:"eulb si yks eht" 单词反转:"blue is sky the" 这样我们就完成了翻转字符串里的单词。中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词就正过来了。如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
2023-11-23 16:15:40
40
原创 力扣每日一题day17[541. 反转字符串 II]
在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。这道题就是模拟,实现题目中规定的反转规则就可以了。,从字符串开头算起,每计数至。
2023-11-21 10:59:49
32
原创 力扣每日一题day16[344. 反转字符串]
反转字符串比反转链表简单一些,也使用双指针法,一个从前往后,一个从后往前,同时向中间移动并交换元素。编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组。、使用 O(1) 的额外空间解决这一问题。不要给另外的数组分配额外的空间,你必须。
2023-11-20 15:09:58
40
1
原创 力扣每日一题day15[18. 四数之和]
四数之和的双指针解法是两层for循环nums[i] + nums[j]为确定值,依然是循环内有left和right下标作为双指针,找出nums[i] + nums[j] + nums[left] + nums[right] == target的情况。三数之和的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下标作为双指针,找到nums[i] + nums[left] + nums[right] == 0。请你找出并返回满足下述全部条件且。
2023-11-19 11:17:28
28
原创 力扣每日一题day14[15. 三数之和]
这么写就是当前使用 nums[i],我们判断前一位是不是一样的元素,在看 {-1, -1 ,2} 这组数据,当遍历到 第一个 -1 的时候,只要前一位没有-1,那么 {-1, -1 ,2} 这组数据一样可以收录到 结果集里。但这里有一个问题,是判断 nums[i] 与 nums[i + 1]是否相同,还是判断 nums[i] 与 nums[i-1] 是否相同。a, b ,c, 对应的就是 nums[i],nums[left],nums[right]注意,输出的顺序和三元组的顺序并不重要。
2023-11-18 18:48:33
41
1
原创 力扣每日一题day13[454. 四数相加 II]
在遍历nums3和nums4数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。这道题目是四个独立的数组,只要找到nums1[i] + nums2[j] + nums3[k] + nums4[l] ==0就可以了。首先定义 一个map,key放a和b两数之和,value 放a和b两数之和出现的次数。遍历nums1和nums2数组,统计两个数组元素之和,和出现的次数,放到map中。,请你计算有多少个元组。
2023-11-17 19:09:55
41
原创 力扣每日一题day12[1. 两数之和]
在遍历数组的时候,只需要向map去查询是否有和目前遍历元素比配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下表,这样才能找到与当前元素相匹配的(也就是相加等于target)那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。set是一个集合,里面存放的元素只能是一个key。
2023-11-16 17:43:16
52
1
原创 力扣每日一题day11 [349. 两个数组的交集]
那么可以发现,貌似用数组做哈希表可以解决这道题目,把nums1的元素,映射到哈希数组的下表上,然后在遍历nums2的时候,判断是否出现过就可以了。而集合(Set)是不允许重复值的。题目特意说明:输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序。用数组来做哈希的题目,都限制了数值的大小,例如只有小写字母,或者数值大小在[0- 10000] 之内等等。所以HashSet是一个没有重复元素的集合,但不保证集合的迭代顺序,所以随着时间,元素的顺序可能会改变。
2023-11-15 09:13:45
27
原创 力扣每日一题day10 [242. 有效的字母异位词]
需要把字符映射到数组也就是哈希表的索引下标上,因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。需要定义一个多大的数组呢,定一个数组叫做record,大小为26 就可以了,初始化为0,因为字符a到字符z的ASCII也是26个连续的数值。那看一下如何检查字符串t中是否出现了这些字符,同样在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
2023-11-14 11:31:57
51
1
原创 力扣每日一题day09 [142. 环形链表 II]
当fast指针与slow指针相遇时,slow指针移动的节点数为x+y,fast指针移动的节点数为x+y+n(y+z),n的含义为fast在环内移动了n圈才遇到slow指针,y+z为一圈内节点的个数。因为fast指针一次移动两个节点,slow一次移动一个节点,所以fast指针移动的节点数=slow指针移动的节点数x2,即(x+y)x2=x+y+n(y+z)。假设从头结点到环的入口节点数为x,环的入口节点fast指针与slow指针相遇节点的结点数为y,从相遇节点再到环的入口节点的节点数为z。
2023-11-13 16:26:03
70
原创 力扣每日一题day08[19. 删除链表的倒数第 N 个结点]
这道题目使用双指针解决,如果要删除倒数第n个节点,则让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾,删除slow所指向的节点就可以了。因为这样,fast和slow同时移动的时候slow才能指向删除结点的上一个结点。(2)定义一个fast指针和slow指针,初始化值为虚拟头节点(dummyHead),删除倒数第n个节点。(1)推荐使用虚拟头节点,便于处理删除实际头节点的逻辑。(4)fast和slow同时移动直到fast指向末尾。(5)删除slow指向的下一个节点。
2023-11-12 13:30:02
91
1
原创 力扣每日一题day07 [206. 反转链表]
最后cur指针指向了null,循环结束,链表也反转完毕。此时我们返回pre指针即可,pre指针就指向了新的头节点。首先使用tmp指针保存cur->next,接下来改变cur->next的指向,将cur->next指向pre。之前链表的头节点是1,反转之后的头节点是5,这里并没有添加或者删除节点,仅仅是改变了next指针的方向。递归法其实和双指针的逻辑是一样的,同样是当cur为空的时候循环结束,不断将cur指向pre的过程。如果在定义一个新的链表,实现链表元素的反转,其实是对内存空间的浪费。
2023-11-11 15:15:37
33
1
原创 力扣每日一题day06[707. 设计链表]
/ 链表变为 1->2->3。// 现在,链表变为 1->3。以指示链表中的上一个节点。假设链表中的所有节点下标从。你可以选择使用单链表或者双链表,设计并实现自己的链表。是指向下一个节点的指针/引用。如果是双向链表,则还需要属性。我们使用设置虚拟头结点来实现。
2023-11-10 10:35:03
33
1
原创 力扣每日一题day05[203. 移除链表元素]
因为单链表的特殊性只能指向下一个结点,刚刚删除的是链表中的第二个和第四个结点,那么如果删除的是头结点又该怎么办?这样就移除了头结点,是不是发现,在单链表中移除头结点和移除其他结点的操作方法不一样,其实在写代码的时候也会发现,需要单独写一段来处理移除头结点的情况。移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。其实可以设置一个虚拟头结点,这样原链表的所有节点都可以按照统一的方式删除。这样是不是就可以使用和移除链表其他节点的方式统一了呢?
2023-11-09 09:16:09
35
1
原创 力扣每日一题day04-[59. 螺旋矩阵 II]
这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开或者左开右闭原则,这样才能以统一的规则画出来。如何画出这个螺旋排列的正方形矩阵?求解本题坚持的是循环不变量原则。每一种颜色代表一条边及遍历的长度,而拐角交给新的边,这就是坚持左闭右开原则,坚持不变量。所有元素,且元素按顺时针顺序螺旋排列的。这道题目考验的是对代码的掌控能力。
2023-11-08 08:38:55
70
1
原创 力扣每日一题day03-209.长度最小的子数组
如果用一个for循环来表示起始位置,那么该如何遍历剩下的终止位置?所以这个循环的索引一定是滑动窗口的终止位置。在暴力解法中一个for循环为窗口的起始位置,一个for循环为窗口的终止位置,用两个for循环完成一个不断搜索的过程。滑动窗口就是不断调整子序列的起始位置和终止位置,从而得到我们想要的结果。移动窗口的起始位置:如果当前窗口的值大于s,则窗口向前移动(即缩小窗口)窗口内的元素:保持窗口内数值总和大于或等于s的最小的连续子数组。移动窗口的结束位置:窗口的结束位置就是for循环遍历数组的指针。
2023-11-07 11:03:31
35
原创 力扣每日一题day02-27.移除元素
暴力解法就是两层for循环,一个for循环遍历数组元素,第二个for循环更新数组。快指针遇到目标值就指向下一个,否则慢指针指向的数组元素更新为快指针指向数组元素。数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。通过一个块指针和一个慢指针在一个for循环下完成两个for循环的工作。快指针:寻找新元素的数组,新元素就是不含有目标值的数组。慢指针:指向更新新数组下标的位置。
2023-11-06 11:07:42
57
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人