- 博客(27)
- 收藏
- 关注
原创 力扣hot100 - 108、将有序数组转换为二叉搜索树
思路:将数组从最中间分为中间节点,左边数组和右边数组,中间作为根节点,左边作为左子树,右边作为右子树,左子树右子树同样取中间节点作为根节点。
2026-02-05 17:29:11
127
原创 力扣hot100 - 101、对称二叉树
思路:判断是不是对称二叉树,本质上是判断根节点左右子树是否可以相互翻转。整体思路:比较左右子树的外边及里边,如果都相等就是对称二叉树。确定遍历顺序:这类题最好用后续遍历左右中,把左右孩子的信息处理完返回给上一层。递归前先判断一些一定是对称或一定是不对称的情况,左右都空、左空右不空、左不空右空、左右值不相等;注意把左右空放前面避免控制针;我们真正要递归处理的情况是左右不空且值相等,这是要判断左右子树外侧及内侧是否相同。
2026-02-05 16:44:14
115
原创 力扣hot100 - 226、翻转二叉树
题目:思路:递归三部曲:参数(root) 终止条件(root == null) 单层递归逻辑(将左右孩子交换,然后不断递归左右孩子)。要注意交换左右孩子时,引用传递的问题,我一开始是将局部变量在交换,实际上的对象完全没有交换。
2026-02-04 20:24:51
101
原创 力扣hot100 - 104、二叉树的最大深度
递归三部曲:参数(root) 结束条件(root==null) 单层递归逻辑(先求左子树的高度,再求右子树高度,然后比较大小拿大的+1就是该root节点的最大高度)。井有多深,树有多高。一般求高度我们用后续遍历,后续遍历是从最下面开始,但是最大深度=最大高度,这里为了方便直接求最大高度。思路:首先理解两个概念--深度和高度。
2026-02-04 20:10:49
96
原创 力扣102、二叉树的层序遍历
思路:将第一层节点加入队列,并记录第一层节点个数size,一个一个弹出节点,弹出size个,每弹出一个都将弹出节点的左右孩子加入队列中。
2026-02-04 19:53:49
177
原创 力扣hot100 - 144、二叉树的前序遍历
整体思路:先将根节点放入栈中,弹出并放入结果集合,再将右、左孩子放入栈,弹出一个并且放入结果集合,将弹出的节点有左孩子放入栈中。弹出时刚好是先左后右。
2026-02-03 15:15:14
26
原创 力扣hot100 - 94、二叉树的中序遍历
整体思路:首先不断向左遍历左孩子,同时将遍历的节点存入栈中,如果当前节点为空,那么此时栈顶的元素就是中序遍历的第一个元素,将该元素弹出并且存入结果集合中,然后遍历该节点的右孩子,如果为空直接从栈里弹出一个节点,并存入结果集合中,不为空则不断向左遍历左孩子。定义一个结果reslut集合存储元素,一个栈存储节点。
2026-02-03 15:08:48
133
原创 力扣hot100 - 148、排序链表
这样slow就指向了左边界的最后一个节点,将slow.next = null就将链表一分为二了,接下来标记好左边分组left和右边分组right的头结点,并不断递归调用上面的函数,知道head==null 或者head.next == null;如图:链表 4 2 1 3 先拆成 4 2 和1 3 再拆成 4和2以及1和3,这四组都只有一个元素,都可以算是有序的,把4 和 2 两组合并为有序的一组 2 4 ,同理 1 3,最后把2 4 和 1 3 合并为有序的一组 1 2 3 4。
2026-01-01 22:54:47
402
原创 力扣hot100 - 21、合并两个有序链表
具体实现:我们需要拿一个哨兵节点dummy 来存储后面的有序的节点(还能便于最后返回结果,return dummy.next,不然返回结果很麻烦),然后用tail来维护合并后有序节点的尾部;不断l1和l2的大小,谁小tial就指向谁,同时小的一方后移;知道一方为null;当 l1 和 l2 都不是空链表时,判断 l1 和 l2 哪一个链表的头节点的值更小,将较小值的节点添加到结果里,当一个节点被添加到结果里之后,将对应链表中的节点向后移一位。时间复杂度O(m+n)空间复杂度O(1)整体思路:如上例所示,
2025-12-25 20:25:27
255
原创 力扣hot100 - 142、环形链表2
这种情况和上面一样:快指针放到头结点,和慢节点同时起步,一步步走,一定会在入环点相遇。因为a相当于一个b和n - 1个c,两个指针走完了b,此时慢指针在入环点,两个节点走n-1个c都会到入环点来。情况1:如果c只绕环走了一圈就相遇了,按照quick走的距离为slow走的距离的两倍可知上面的白色字体列式,得出a = b;情况2:如果c只绕环走了n圈才相遇,可知:a+nc+c-b=2(a+c-b) 化简 a=b+(n-1)c 其中 n≥1。如果有环那么它们一定会相遇。时间复杂度:O(n) 空间复杂度:O(1)
2025-12-24 17:14:32
420
原创 力扣hot100 - 1、两数之和
遍历数组时,将先判断(target - nums【i】)是否在哈希表存在,存在则证明nums【i】是要找的值,如果不存在,则把nms【i】放入哈希表。时间复杂度o(n2)空间复杂度o(1)两个for循环暴力遍历。时间复杂度o(n)空间复杂度o(n)
2025-12-13 19:55:20
163
原创 力扣hot100 - 234、回文链表
找到链表中间--快慢指针法:快慢指针同期点,慢指针走一步,块指针走两步,在快指针及快指针下一个元素不为空的情况下,不断往前走;最后慢指针停下来的地方就是链表中间的地方(如果是偶数个,那就是中间偏右)。最近学得心好累,很烦,唯一能坚持下来的就是一天一道算法一篇博客了。首先我们要先找到链表的中间,然后将中间及其后面部分反转。左指针右移,右指针左移,不断判断是否相同即可。不太建议该方法,实际上相当于在数组上的判断。反转后半链表:见我上篇文章--反转链表。思路二:反转后半链表后双指针。
2025-10-30 19:52:25
914
原创 力扣hot100 - 206、反转链表
我们将null -- > a -->b --> c 反转为 c --> b--> a-- >null,我们只需拿两个指针p (前)和 pp(后),指向前两个元素,pp 指向 p 即可 ,然后不断迭代。但是当pp 指向了p之后,如null < -- a,b -- >c,a和b之间的联系断开了,所以我们需要提前标记一下pp.next,也就是b元素。建议先搞懂上面的双指针迭代后,再来递归,其实本质上的逻辑还是双指针迭代。当遍历到pp为空时,所有元素反转完毕,p就是我们想要的头结点。
2025-10-29 21:08:29
486
原创 力扣hot100 - 160、相交链表
拿指针h1和h2分别遍历链表a和b,同时遍历,当其中一个为null时指向另一个链表的头结点,直到两个指针指向的值相同。为什么可以这样,其实这就相当于h1遍历链表a+b,指针h2遍历链表b+a。遍历另一个链表,判断是否有相同元素,有则返回无则继续遍历。时间复杂度为o(a + b)//遍历了两个链表。如图,当遍历到8第二个8时两个指针会同时指向8。时间复杂度为o(a+b),空间复杂度为o(1)遍历一个链表,将所有元素放到集合中;拿一个哈希集合存储链表节点;a b分别为链表a b的长度。空间复杂度为o(a)
2025-10-28 15:33:11
633
原创 力扣100 - 240、搜索二维矩阵II
开的那边不需要+1 或 -1;//因为开的这边本身就不会进入循环,如果+1 或者 -1 了会把应该进入循环的数不进人循环。//l <= r而不是l < r,如果出现r = l = mid 没有等于则会跳过。//【1,2),当 l = r = m =1时,不应该进入循环。//mid已经不符合取值了。左闭右开区间 和左开右闭区间和上面左开右开区间写法区别。对每一行进行二分查找。
2025-10-27 20:22:44
256
原创 力扣hot100 - 48、旋转图像
模拟这个顺时针旋转的过程,拿一个temp变量存储左上角的值;左下角 -- >左上角,右下角 -- >左下角 , 右上角 -->右下角 ,temp -- >右上角;这样我们就模拟完成了四个角的顺时针转换,我们只需在各个角对应的位置上偏移1个位置即可完成这一行的顺时针转换(如图中的2684);然后我们将范围缩小,不断遍历。
2025-10-26 11:28:01
443
原创 力扣hot100 - 54、螺旋矩阵
取这个数组的左边界left = 0、右边界right = n+1、上边界top = 0、下边界botton = m+1。按照左下右上这个顺序遍历。思路一:模拟螺旋的过程。
2025-10-25 20:35:23
332
原创 力扣hot100 - 73 矩阵置零
后续我们根据第0行和第0列的数据就可以判断哪些数据需要修改为0;但是第0行第0列的数据重合了,这个数据只能表示第0行或者第0列的数据为0,所以我们要拿出一个变量表示第0行的数据是否为0,而第0行第0列的数据表示第0列的数据是否为0;一个一维数组标记为0的行,一个标记一维数组为0的列。拿出一个和原数组一样的副本数组,遍历原数组,遇到0则修改当前数组同行同列的数组。遍历原数组,遇到为0的值,将对应第0行和第0列的数据修改为0;时间复杂度o(m*n)空间复杂度o(m*n)思路二:用两个一维数组标记。
2025-10-25 19:25:02
489
原创 力扣hot100 - 238、除自身以外数组的乘积
前缀积:数组当前元素前面(不包括本身)所有元素的乘积。后缀积:数组当前元素后面(不包括本身)所有元素的乘积。除自身以外数组的乘积 = 前缀积 * 后缀积。思路一:前缀积*后缀积。
2025-10-23 10:23:58
369
原创 力扣hot100 - 189、轮转数组
整体思路:将当前数的元素i移到额外素(i+k)%n的位置(n为数组长度);元素i经过第k次轮转回到第i+k的位置上,但i+k可能大于n,故%可以把元素完美放到额外素组上。可以观察一下,将原来的数组先反转,再对比目标数组。我们只需将反转后的数组以k-1为界分别进行反转即可。弊端:空间复杂度为o(n)思路二:在原来的数组上反转。思路一:使用额外数组。
2025-10-22 22:11:43
976
原创 力扣hot100 - 56、合并区间
从左到右遍历二维数组,对比当前数组的右边界lr和集合中最后一个数组左边界rl,如果lr > rl则代表无重合,直接将当前数组放入存储的集合中;如果lr <= rl则有重合,更新集合中最后一个数组的右边界。这个方法排序二维数组我还是不太懂。1、将二维数组里的数组按照左边界升序排序。刚开始写有点思路,但是具体实现有点困难。将二维数组里的数组按照左边界升序排序;对二维数组里的数组按照右边界升序排序。2、返回值list转化为二维数组。拿一个集合存储去重后的数组;先将第一个数组放入集合中;
2025-10-21 16:03:10
409
原创 力扣hot100 - 53、最大数组和
细节:min初始化为Integer.MIN_VALUE;不然当第一个元素为负数时,min会初始化为0。具体实现:pre记录前缀和,min记录当前位置最小前缀和,max记录当前位置最大和。整体思路:记录当前位置最小前缀和(初始为0)和最大前缀和,最大前缀和-最小前缀和 即为 最大和。
2025-10-20 15:06:20
356
原创 力扣hot100 - 560、和为k的子数组
具体实现:用一个集合存储前缀和,key为当前位置前缀和,value为该key前缀和的次数(两个位置前缀和可能一致),用count表示子数组个数,用pre表示前缀和;遍历数组,将当前元素加入pre即表示当前元素前缀和,判断集合中pre - key是否存在,存在则count + (pre- key)对应value;判断集合中pre是否存在,存在则value++,不存在则将(pre,1)加入集合。整体思路:判断当前位置前缀和 - 前面某个位置前缀和 = key,即可认定为一个连续子数组。
2025-10-19 12:01:30
523
原创 力扣hot100 - 438、找到字符串中所有字符字母的异位词
将字符串p转为字符数组后排序(排序后的字符数组叫pp),将字符串s转为字符数组,遍历,取其中pp长度的字符数组,将其排序(排序后的字符数组叫ss),比较ss和pp是否相等,相等则相同,将索引加入返回集合。核心思想是取s里和p相同字符串的长度的字符串,判断他们字符个数是否一致。为什么是26,英文字母为26位,我们用 当前字母 - ‘a’即可得到索引(ASSCI码方面知识),这样就不用存储字母了,非常方便。拓展思路:思路二也可以利用HashMap实现,key放字母,value放数量;
2025-10-18 16:27:00
411
原创 力扣hot100 - 3、无重复字符的最长子串
具体实现:用一个set集合来存储窗口里的元素,set集合有去重的功能;l=0,r=0,遍历字符串,set中不存在则添加,r右移,存在则删除l,l右移。左指针l指向窗口左边界,右指针r指向窗口右边界;只要窗口没有重复元素,r右移;若有重复元素,l右移;效率一般,后续应该还有优化空间。
2025-10-17 11:18:57
276
原创 力扣hot100-49、字母易位词分组-128、最长连续序列-283、移动零-11、盛最多水的容器-15、三数之和
思路:将数组放到哈希表中去重;在这个哈希表中,判断当前数值-1是否存在(也就是判断是否为起点),不存在则证明是起点,进入一个循环,不断判断当前数值+1是否存在,存在则序列数+1,不存在则结束。将数组中的字母按照a~z的顺序排序,排序后的字母作为HashMap的一个key,value为一个List,List里存与key相同的值。将字符串转化为字符数组。
2025-10-13 20:51:17
495
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅