- 博客(75)
- 收藏
- 关注
原创 LeetCode(python)22.括号生成
2.递归单层逻辑:选择左括号的数量 < n,则可以继续选,即处理下一个左括号;选择右括号的数量要 < 左括号的数量,则可以继续选,即处理下一个右括号。1.递归终止条件:如果选的括号总数 == 2 * n,那么找到一个组合(在递归时使用剪枝,保证所有到达终止条件的组合都合法),存进答案。“选与不选”:对于每一个左括号都有选或不选,对于每一个右括号都有选或不选,很明显的递归思路。3.递归参数:由第二步可知,我们需要知道此时的括号组合、左括号的数量、右括号的数量。
2026-01-06 10:53:49
311
原创 LeetCode(python)39.组合总和
给你一个 无重复元素 的整数数组 和一个目标整数 ,找出 中可以使数字和为目标数 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 对于给定的输入,保证和为 的不同组合数少于 个。示例 1:输入:candidates = [2,3,6,7], target = 7输出:[[2,2,3],[7]]解释:2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意
2026-01-05 22:47:29
285
原创 LeetCode(python)17.电话号码的字母组合
因为python的字符串是不可变类型,所以使用temp + char后,并没有改变temp的值,而是复制了一个新的字符串,所以backtrack()之后不需要使用temp - char还原,本身就没有变。(1)单层逻辑:对当前的数字,我要遍历选取其所映射的字母组合,选好一个就与当前的字符串拼接,并进行下一个数字的处理。(3)终止条件:当拼接的字符串的长度 == 输入的数字串的长度,说明找到了一个组合,存进res答案中。最直接的思路:对输入的数字串挨个处理,遍历选取当前数字的字母组合,选好一个就处理下一个。
2026-01-03 11:01:29
331
原创 LeetCode(python)78.子集
res.append(temp[:]),不能写成res.append(temp),这样存的是temp的引用,后续会随着递归而改变。(2)不选当前元素->把它从临时子集中剔除->继续决策下一个元素(回溯)2.终止条件——当所有数字都决策过了,就存入此次递归的结果。(1)选当前元素->加入临时子集->继续决策下一个元素。返回该数组所有可能的子集(幂集)。(2)把决策后的子集收集到最终的结果中。(1)对每个数字进行决策,选还是不选。1.递归函数要做什么。
2026-01-02 11:30:51
280
原创 LeetCode(python)208.实现Trie(前缀树)
(2)从根节点开始,如果c在当前节点的子节点中,那么就以此子节点为下一个节点,同时进行下一个字符的添加;如果c不在,那么就创建一个节点,作为c,同样进行下一个字符的添加。仅由小写英文字母组成——可以看作是26叉树,每个节点的子节点可以用一个长度为26的数组存储,根节点不存储值。(2)如果c不在当前节点的子节点中,return False;(1)要有一个用于存储子节点的数组——children = [None] * 26。(2)要有一个标志这个节点是否是字符串的结尾的变量——is_end = True。
2025-12-23 10:58:32
894
原创 LeetCode(python)994.腐烂的橘子
左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个方向上。这道问题的核心是多源广度优先搜索,需要模拟“腐烂橘子同步感染新鲜橘子的过程”——BFS。(1)记录当前队列的长度——这是当前分钟需要扩散的腐烂橘子数量(同一层)= 0,存在无法被感染的橘子,返回-1。因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0。(1)若fresh == 0,所有橘子感染,返回时间。(2)把腐烂橘子的坐标入队,以备后续处理。(3)每处理一层,时间 + 1。(1)统计新鲜的橘子数。
2025-12-19 11:42:54
303
原创 LeetCode(python)——236.二叉树的最近公共祖先
(2)left为空,right不为空,说明p、q在右子树中,那么right就是最近公共祖先,return right(left不为空,right为空同理)中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大((3)left、right都不为空:说明p、q在当前访问的节点的左右子树上,当前节点就是最近公共祖先,return node。因为根据定义最近公共祖先节点可以为节点本身。的最近公共祖先是节点。
2025-12-17 10:22:43
319
原创 LeetCode(python)——105.从前序与中序遍历序列构造二叉树
(1)递归结束条件:如果前序or中序序列为空,说明已遍历结束,return None。(2)创建根节点:取前序序列的第一个元素。,请构造二叉树并返回其根节点。2.中序序列——划分左右子树。1.前序序列——找根。
2025-12-15 10:31:06
227
原创 LeetCode(python)199.二叉树的右视图
想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。在遍历当前层时,用n记录当前层有多少个节点,并判断是否为最后一个节点。很自然的一个想法——二叉树的层序遍历,输出每一层的最后一个节点值。
2025-12-11 19:36:16
236
原创 LeetCode(python)230.二叉搜索树中第k小的元素
有一个需要注意的点:self.result is not None!so,中序遍历一遍二叉搜索树,在遍历的过程中计数,就可以找到第k小的元素了~前一个是严格判断是否为空,后一个是判断布尔值是否为0。核心思路:二叉搜索树的中序遍历是升序序列。,请你设计一个算法查找其中第。小的元素(从 1 开始计数)。给定一个二叉搜索树的根节点。
2025-12-10 09:54:54
200
原创 LeetCode(python)98.验证二叉搜索树
1.首先明确二叉搜索树:任意节点的左子树的值 < 当前节点的值;节点的右子树的值 > 当前的值。对于root而言,没有父节点,上下界可设置为节点值的min和max,即[-inf, inf]根节点的值是 5 ,但是右子节点的值是 4。递归遍历每个节点,为每个节点传递合法的取值范围。,判断其是否是一个有效的二叉搜索树。2.核心思路:递归 + 边界约束。给你一个二叉树的根节点。
2025-12-09 10:12:48
355
原创 LeetCode(python)108.将有序数组转换为二叉搜索树
仔细分析易知,整个二叉树的根节点是数组中间那个数,其左节点必在数组左边;同时,其左右两边都是要继续转换为平衡二叉搜索树,这是一个与原问题相似的子问题——递归~4.return 根节点 = TreeNode(值,left,right)[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。排列,请你将其转换为一棵 平衡 二叉搜索树。1.找到数组中点(长度 // 2)2.left = 转换为平衡二叉树。3.right =转换为平衡二叉树。
2025-12-08 09:14:44
238
原创 102.二叉树的层序遍历
在脑海中模拟一下层序遍历:先是root,然后是root的左右节点,然后是root左节点的左右节点,然后....题目还要求了按行输出,所以在(2)里面要注意处理一下:遍历完当前队列中所有的节点就是一行。(2)遍历双端队列,当访问到某节点时,判断其是否有左右节点,如果有,则存进队列,等待访问。有点熟悉了,一个进一个出...!这不就是队列吗,bingo!(即逐层地,从左到右访问所有节点)。(3)直至队列为空,所有节点都已访问。(1)用双端队列存储需要访问的节点。那么思路就非常简单了。
2025-12-07 12:00:02
220
原创 LeetCode(python)——543.二叉树的直径
3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。二叉树的直径:某一个节点的左子树的高度 + 其右子树的高度。3.返回这个节点的高度,以便其父节点计算左右子树的高度。这条路径可能经过也可能不经过根节点。是指树中任意两个节点之间最长路径的。1.计算每个节点的左子树和右子树的高度。给你一棵二叉树的根节点,返回该树的。由它们之间边数表示。
2025-12-06 11:43:28
214
原创 LeetCode(python)——148.排序链表
(1)找中点——快慢指针找中点,但需要注意!由于存在奇偶长度的链表,所以这个中点应该是正中或者偏左一个(否则会存在死循环)(让中点的next = None即可)2.按序合并(比大小即可)
2025-12-03 00:12:16
218
原创 LeetCode(python)——24.两两交换链表中的节点
(3)注意此时确实完成了两个节点的交换,但是会出现 ....1->2->3<-4这样的情况,所以需要存一下两个交换节点的前一个节点,将前一个节点.next指向第二个节点,完成.....1->2->4->3。给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。同时,考虑到处理第一对节点交换不存在前一个节点,因此可以创建一个虚拟节点,指向第一个节点。(2)第二个节点的next 要指向第一个节点。
2025-11-28 22:38:46
200
原创 LeetCode(python)——19.删除链表的倒数第 N 个结点
(3)此时慢指针的下一个节点就是要删除的节点,直接删除即可。(2)快慢指针一起走,直到快指针走到链表尾。给你一个链表,删除链表的倒数第。个结点,并且返回链表的头结点。(1)快指针先走n步。
2025-11-27 18:46:51
224
原创 LeetCode(python)——2.两数相加
两个链表对应位置的数逐个相加,用变量存进位情况,得到的数存进新链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。的链表,表示两个非负的整数。它们每位数字都是按照。请你将两个数相加,并以相同形式返回一个表示和的链表。的方式存储的,并且每个节点只能存储。
2025-11-27 18:42:52
269
原创 LeetCode(python)——21.合并两个有序链表
用两个指针分别遍历两个有序链表,逐个将较小的值接进新链表,遍历结束,如果某个链表还有剩余,直接接入新链表即可。新链表是通过拼接给定的两个链表的所有节点组成的。将两个升序链表合并为一个新的。
2025-11-25 10:32:48
238
原创 LeetCode(python)——142.环形链表 II
所以当fast从head开始走,slow从相遇位置走,那么当fast走了a步(环的起点)时,slow走了k * b - c步,也回到了环的起点,两个指针再次相遇,返回此时的位置,即环的起点。非环部分长度设为a,环长设为b,假设快慢指针相遇时,slow走了a + c,则fast走了2 *(a + c)(1)让fast指向head链表头,一次走一步,slow从上一步的位置开始,一次一步。(1)slow、fast从头开始,slow一次走一步,fast一次走两步。(2)slow和fast相遇的节点,就是环的起点。
2025-11-24 11:13:43
429
原创 LeetCode(python)——141.环形链表
指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数。来表示链表尾连接到链表中的位置(索引从 0 开始)。当链表有环时,快慢指针走到环内时,必然会相遇。如果链表中有某个节点,可以通过连续跟踪。链表中有一个环,其尾部连接到第二个节点。链表中有一个环,其尾部连接到第一个节点。当链表没有环时,快指针会率先走到链表尾部。快指针一次走两步,慢指针一次走一步。仅仅是为了标识链表的实际情况。,判断链表中是否有环。给你一个链表的头节点。
2025-11-23 16:09:07
151
原创 LeetCode(python)——234.回文链表
(3)反转之后就可以比较了,当然,存在奇数和偶数长度的问题,当我们找中点时,链表后半部分的长度一定是<=前半部分的,所以只需要遍历后半部分,和前半部分不断比较即可~fast一次走两步,slow一次走一步(x = vt,fast = 2 * t,slow = 1 * t,当fast走完链表,意味着slow刚好走了链表的一半)1 2 3 3 2 1:找到的中点是左3,反转之后左边是123,右边是123,以右边为准对比。1 2 3 2 1:找到的中点是3,反转之后左边是123,右边是12,以右边为准对比。
2025-11-22 22:28:17
249
原创 LeetCode(python)——206.反转链表
在改变指针的方向时,主要是找不到下一个位置,所以在遍历的过程中,用next_temp变量存下一个节点的位置。,请你反转链表,并返回反转后的链表。curr指向当前处理的节点。pre指向前一个节点。
2025-11-21 22:08:10
200
原创 LeetCode(python)——160.相交链表
请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。从各自的表头开始算起,链表 A 为 [1,9,1,2,4],链表 B 为 [3,2,4]。- 相交的起始节点的值。
2025-11-20 20:27:12
955
原创 LeetCode(python)——240.搜索二维矩阵II
同理,从矩阵的左下角开始也OK,总之,要存在“不同方向对应偏大偏小的情况”,而不是像左上角和右下角一样,往哪边走都是增大/减小。如果target > 当前位置,则往下走(y + 1)如果target < 当前位置,则往右走(x - 1)编写一个高效的算法来搜索。从矩阵的右上角开始遍历。
2025-11-19 18:55:59
178
原创 LeetCode(python)——48.旋转图像
旋转图像,这意味着你需要直接修改输入的二维矩阵。请你将图像顺时针旋转 90 度。转置:对上三角(i < j)每一个元素的行列交换。一个简单神奇的思路,先转置后反转每一行。反转:row.reverse()使用另一个矩阵来旋转图像。
2025-11-18 11:32:12
228
原创 LeetCode(python)——54.螺旋矩阵
顺时针方向:从左往右(结束后调整上边界top + 1),从上往下(结束后调整右边界right - 1),从右往左(结束后调整下边界bottom - 1),从下往上(结束后调整左边界left + 1)(2)按照顺时针方向依次遍历,当top > bottom,left > right时就停止。,返回矩阵中的所有元素。模拟螺旋轨迹,动态调整边界。(1)定义矩阵的上下左右。
2025-11-17 14:13:42
353
原创 LeetCode(python)——73.矩阵置零
3.优化:先单独处理原数组的第一行、第一列(用bool变量标识是否需要置零),再利用原数组的第一行和第一列存需要置零的行和列——空间复杂度O(1)2.优化:将ans拆分成两个数组:一个存需要置零的行,一个存需要置零的列,分别遍历这两个数组,将原数组置零——空间复杂度O(m + n)1.非常直观的想法:遍历矩阵,用一个ans数组存矩阵中的零存在的位置,再遍历ans,找到对应行、列,置零——空间复杂度O(m*n),则将其所在行和列的所有元素都设为。的矩阵,如果一个元素为。
2025-11-17 11:35:10
307
原创 LeetCode(python)——238.除自身以外数组的乘积
优化:如果要想在空间复杂度为O(1)的情况下实现,则无需使用前缀数组、后缀数组,直接存进ans。(1)从前往后,遍历数组,对当前的每一个数计算前缀乘积。(2)从后往前,遍历数组,对当前的每一个数计算后缀乘积。之中任意元素的全部前缀元素和后缀的乘积都在。(3)答案 = 前缀乘积 * 后缀乘积。之外其余各元素的乘积。时间复杂度内完成此题。
2025-11-17 09:29:44
285
原创 LeetCode(python)——56.合并区间
(2)intervals[i][1] > intervals[i+1][0]时,存在重叠,且合并区间的右端点为两者中较大的值。(1)intervals[i][1] < intervals[i+1][0]时,不可能重叠,直接存进答案。二维数组中,按照数组中第一个元素排序:sort(key = lambda x : x[0])区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].区间 [1,4] 和 [4,5] 可被视为重叠区间。区间 [1,4] 和 [4,7] 可被视为重叠区间。
2025-11-13 19:45:01
322
原创 LeetCode(python)——53.最大子数组的和
3.遍历前缀和,用min_pre记录最小的前缀和的值,用当前的前缀和 - min_pre,用max()更新答案,用min()更新min_pre。,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。再次重申:数组无序——前缀和;数组有序——双指针、滑动窗口。连续子数组 [4,-1,2,1] 的和最大,为 6。2.要求最大的子数组和:即求最大的前缀和之差。是数组中的一个连续部分。1.求出每个下标的前缀和。很明显的一道前缀和~
2025-11-12 15:31:09
219
原创 LeetCode(python)——560.和为k的子数组
非常好,那么我们就可以在遍历数组计算每个下标前缀和的时候,计算target = pre[j] - k,如果已经记录的前缀和pre[i] == target,就说明对于pre[j]而言,找到了一个子数组[i....j-1]如果已知每个下标的前缀和,那么[i....j-1]这个子数组的和为k,则意味着pre[j] - pre[i] == k,左右变换一下可以得到:pre[i] = pre[j] - k。(1)前缀和——pre[i]定义为数组前i个元素的和。数组有序——滑动窗口。
2025-11-11 16:09:00
161
原创 LeetCode(python)——438.找到字符串中所有字母异位词
3.用differ记录s和p的差值(记录count中所有非0数的数量),当differ = 0 时,意味着此时窗口中的字母和p是字母异位词,记录答案。起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。不考虑答案输出的顺序。
2025-11-10 16:29:36
307
原创 LeetCode(python)——3.无重复字符的最长子串
4.找好右边界,也就意味着当前的左边界已经完成它的使命了,把它从curr剔除出去~找下一个。3.只要没有到达字符串的边界,且没有与curr中的字符重复,则不断移动右边界。,所以其长度为 3。1.用字符串curr存当前的最长子串,ans记录最长子串的长度。2.遍历滑动窗口的左边界,不断探索右边界。,请你找出其中不含有重复字符的。请注意,你的答案必须是。因为无重复字符的最长子串是。因为无重复字符的最长子串是。因为无重复字符的最长子串是。,所以其长度为 1。,所以其长度为 3。
2025-11-09 15:48:38
137
原创 Leetcode(python)——11.盛最多水的容器
在上面的公式中,随着指针的移动,距离必然越来越小,那么我们想要容纳的水量最多,就得想办法提高指针的高度,于是我们在移动双指针时,就应该移动高度较小的那个指针。图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。头尾指针,一个公式:容纳的水量 = 两个指针的距离 * min(两个指针的高度)轴共同构成的容器可以容纳最多的水。找出其中的两条线,使得它们与。返回容器可以储存的最大水量。
2025-11-08 22:23:23
142
原创 LeetCode(python)——15.三数之和
先排序,避免重复处理元素;再遍历三元组中的第一个值,第二个和第三个值使用双指针寻找。使用双指针,一头一尾,如果此时寻找的第二个值与前一个第二个值相同,则跳过;如果此时第一个、第二个值和第三个值相加大于0,则移动尾指针;如果此时头尾指针相遇,则直接跳出循环(找完了!如果此时相加等于0,则存入答案输出。不同的三元组是 [-1,0,1] 和 [-1,-1,2]。注意,输出的顺序和三元组的顺序并不重要。答案中不可以包含重复的三元组。唯一可能的三元组和不为 0。唯一可能的三元组和为 0。(2)遍历(注意查重)
2025-11-08 22:08:17
356
原创 LeetCode(python)——283.移动零
让right指针去寻找非零元素,即和left所指位置交换的元素。让left指针表示零所在的位置,即需要进行交换操作的位置。移动到数组的末尾,同时保持非零元素的相对顺序。,必须在不复制数组的情况下原地对数组进行操作。,编写一个函数将所有。
2025-11-06 20:20:34
131
原创 LeetCode(python)——128.最长连续序列
1.遍历数组,看当前值是否可能是连续序列的开头(查找当前值-1,是否在数组中,如果在,那必不可能是连续序列的开头)接着查找当前值+1,当前值+2.....是否在数组中,边查找,边计数、,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。最长数字连续序列是 [1, 2, 3, 4]。3.找到一个完整的连续序列后,与上一次找到的比较长度,取max。2.如果不是开头,就不管,跳过;请你设计并实现时间复杂度为。给定一个未排序的整数数组。
2025-11-05 21:23:53
165
原创 LeetCode(python)——49.字母异位词分组
计数,互为字母异位词的两个字符串包含的字母相同,故可以将每个字符串中出现的字母次数以字符串的形式表示,作为哈希表的Key值。由于只包含小写字母,故用大小为26的数组即可。对字符串数组中的每个字符串排序,以这个排序作为Key值,当两个字符串的排序相同时,存进同一个列表。给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。在 strs 中没有字符串可以通过重新排列来形成。是字母异位词,因为它们可以重新排列以形成彼此。是字母异位词,因为它们可以重新排列以形成彼此。
2025-11-05 21:16:01
252
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅