Leetcode hot100 补刷部分 Ⅱ

目录

链表 

2024.5.8

160 相交链表

 2024.5.9

206 反转链表

234 回文链表

141 环形链表

 2024.5.10

 142 环形链表 Ⅱ

 21 合并两个有序链表

2024.5.11

2 两数相加

19 删除链表的倒数第N个结点

 2024.5.12

24 两两交换链表中的节点

 25 K个一组翻转链表

2024.5.13

138 随机链表的复制

148 排序链表

2024.5.14

146 LRU缓存

 二叉树

94 二叉树的中序遍历

 2024.5.15

104 二叉树的最大深度

​编辑 226 翻转二叉树

 101 对称二叉树

 2024.5.16

543 二叉树的直径

102 二叉树的层序遍历

 108 将有序数组转化为二叉搜索树

 98 验证二叉搜索树

2024.5.17

230 二叉树中第k小的元素

199 二叉树的右视图

114 二叉树展开为链表

2024.5.18

105 从前序与中序遍历构造二叉树

 2024.5.19

437 路径总和

236 二叉树的最近公共祖先

 124 二叉树中的最大路径和

图论

2024.5.20

200 岛屿数量

2024.5.21

994 腐烂的橘子

2024.5.24

207 课程表

208 实现Trie(前缀树)

 回溯

46 全排列

2025.5.25

78 子集 

 17 电话号码的字母组合

2024.6.3

39 组合总和

 22 括号生成

2024.6.4 

79 单词搜索

 131 分割回文串

链表 

2024.5.8


160 相交链表

         

(a+c)+b=(b+c)+a 两个指针就会相遇

   

 2024.5.9


206 反转链表

使用一个前驱节点,一直迭代将pre和cur之间的指针翻转,直到cur指向null时结束

234 回文链表
  1. 快慢指针,找到中点结点。
  2. 翻转中点结点(slow)到链表结尾的所有结点。
  3. 普通遍历比较翻转后的链表,和原始链表头结点到中点结点的元素是否相等。

141 环形链表

快慢指针的初始位置不一样;慢在第一个,快在第二个

!只是用来判断快慢指针是否会相遇,相遇的地方不知道 !

 2024.5.10


 142 环形链表 Ⅱ

条件跟上面的不一样,所以可以让fast和slow初始都在head

 21 合并两个有序链表

时间复杂度:O(n+m),最多循环m+n次。每次加入一个节点;

空间复杂度:O(1),创建节点只占用常数级别的空间

2024.5.11


2 两数相加

链表倒着看是这个数的高位到低位,长度不相同还是从第一个节点开始对应相加,每次相加考虑上一个的进位,并且更新这次的进位,如果有一个为null的时候,就将其值取为0继续计算,直到两个链表都为null;最后还要考虑最高位的进位。有一个虚拟头节点保持不动

19 删除链表的倒数第N个结点

双指针,虚拟头节点

 2024.5.12


24 两两交换链表中的节点

 虚拟头节点;双指针

 25 K个一组翻转链表
  1. 找到待翻转的k个节点(注意:若剩余数量小于 k 的话,则不需要反转,因此直接返回待翻转部分的头结点即可)。
  2. 对其进行翻转。并返回翻转后的头结点(注意:翻转为左闭右开区间,所以本轮操作的尾结点其实就是下一轮操作的头结点)。
  3. 对下一轮 k 个节点也进行翻转操作。
  4. 将上一轮翻转后的尾结点指向下一轮翻转后的头节点,即将每一轮翻转的k的节点连接起来。

2024.5.13


138 随机链表的复制

算法流程:

  1. 若头节点 head 为空节点,直接返回 null。
  2. 初始化: 哈希表 dic , 节点 cur 指向头节点。
  3. 复制链表:a. 建立新节点,并向 dic 添加键值对 (原 cur 节点, 新 cur 节点) 。b. cur 遍历至原链表下一节点。
  4. 构建新链表的引用指向:构建新节点的 next 和 random 引用指向。cur 遍历至原链表下一节点。
  5. 返回值: 新链表的头节点 dic[cur] 。

148 排序链表

使用归并排序,时间复杂度为O(nlogn);使用迭代法,空间复杂度为O(1)

主要是将step从1,2,4,8...,遍历全部链表每次按这个长度进行两两归并

关键是断链合并

第一次,while循环将链表依次分为1长度的段,并两两合并,合并之后使用pre.next进行连接

得到的是长度为 的有序链表的连接

第二次,while循环将链表依次分为2长度的段,并两两合并,合并之后使用pre.next进行连接

得到的是长度为 的有序链表的连接

...直到整个有序

2024.5.14


146 LRU缓存

LRU 缓存机制可以通过哈希表辅以双向链表实现,我们用一个哈希表和一个双向链表维护所有在缓存中的键值对。

  • 双向链表按照被使用的顺序存储了这些键值对,靠近头部的键值对是最近使用的,而靠近尾部的键值对是最久未使用的。
  • 哈希表即为普通的哈希映射(HashMap),通过缓存数据的键映射到其在双向链表中的位置。

对于 get 操作,首先判断 key 是否存在:

  • 如果 key 不存在,则返回 −1;
  • 如果 key 存在,则 key 对应的节点是最近被使用的节点。通过哈希表定位到该节点在双向链表中的位置,并将其移动到双向链表的头部,最后返回该节点的值。

对于 put 操作,首先判断 key 是否存在:

  • 如果 key 不存在,使用 key 和 value 创建一个新的节点,在双向链表的头部添加该节点,并将 key 和该节点添加进哈希表中。然后判断双向链表的节点数是否超出容量,如果超出容量,则删除双向链表的尾部节点,并删除哈希表中对应的项;
  • 如果 key 存在,则与 get 操作类似,先通过哈希表定位,再将对应的节点的值更新为 value,并将该节点移到双向链表的头部。

访问哈希表的时间复杂度为 O(1),在双向链表的头部添加节点、在双向链表的尾部删除节点的复杂度也为 O(1)。而将一个节点移到双向链表的头部,可以分成「删除该节点」和「在双向链表的头部添加节点」两步操作,都可以在 O(1) 时间内完成。

 二叉树

把之前做过的又做一遍,都忘记了

94 二叉树的中序遍历
  • 递归:隐式地维护

  •  迭代:明确创建一个栈

 2024.5.15


104 二叉树的最大深度

树的后序遍历 / 深度优先搜索往往利用 递归 或  实现

树的层序遍历 / 广度优先搜索往往利用 队列 实现

  • 递归实现(深度优先搜索 DFS)

  • 层序遍历(广度优先搜索 BFS)

记录每层的长度,只要size>0,就一直将第一个节点poll出,size--,并将这个节点的左右子节点offer加入队列;直到size为0这一层结束,层数++;最终队列为空结束。

 226 翻转二叉树

后序遍历递归翻转

 101 对称二叉树

即判断左右两个子树是否可以相互翻转。需要收集左右孩子的信息,然后返回给父节点,才能知道是否是对称二叉树,所以需要后序遍历

一个返回值为boolean的compare函数,参数为左右两个子树。

结束条件:左空右不空,左不空右空;左右都空,左右不空但不相等,这时只剩下一种相等的情况,递归比较左的左和右的右以及左的右和右的左,最后如果两个都为true则返回true。(这时说明以这两个为节点的树是互相翻转的)

 2024.5.16


543 二叉树的直径

二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 

102 二叉树的层序遍历

二级列表,队列实现

 108 将有序数组转化为二叉搜索树

取根节点之后,如果左右子树长度是偶数的话,取最中间的左边还是右边作为根节点都是可以的,可以构造不同的二叉树;明确递归的左右区间定义

 98 验证二叉搜索树

引入前驱节点pre,中序遍历递归

2024.5.17


230 二叉树中第k小的元素

采用中序遍历,用栈存储节点,后进先出,root不为空或者栈不为空的时候进行循环,如果root不为空,就要将root进栈,一直向左遍历;然后将栈顶元素给pop,这时候pop出的就是比较小的节点,k--,判断k是否等于0,若等于 break结束循环,若不等,将root赋值为其右节点(相当于有个回溯的过程,pop出这个节点,就要把其右孩子进栈,进行循环判断)

199 二叉树的右视图

层序遍历记录每层的最后一个节点的值即可

114 二叉树展开为链表

2024.5.18

105 从前序与中序遍历构造二叉树

 2024.5.19

437 路径总和

定义节点的前缀和为:由根结点到当前结点的路径上所有节点的和。curr-targetSum能在HashMap中找到,说明从找到的那个节点的下一个节点到当前节点的路经总和为targetSum。

使用HashMap存储,key为节点的前缀和,value为和出现的次数。

节点的值-10^9 <= Node.val <= 10^9,总和curr可能会很大,因此用Long

236 二叉树的最近公共祖先

要想从下往上找,并向上返回,可以使用后序遍历递归

因为题目中说每个节点的值都不一样,并且p!=q,因此有两种情况:

  • p和q分别在一个子树的左右子树中,那么左和右遍历结果都不为空(左和右中必分别有p和q),则可以返回该root
  • 如果这个root就是p或q,那么就返回root,不用管该节点的下面是不是有另一个值;如果有就是向上传递root;如果没有,就又成为了第一种情况。

 124 二叉树中的最大路径和

节点的最大贡献值在以该节点为根节点的子树中寻找以该节点为起点的一条路径,使得该路径上的节点值之和最大。

  • 空节点的最大贡献值等于0。
  • 非空节点的最大贡献值等于节点值与其子节点中的最大贡献值之和(对于叶节点而言,最大贡献值等于节点值)。

 后序遍历,先看左右子树再考虑加不加入当前节点的最大路径和中

每次更新最大路径和的值,返回的是每个节点的最大贡献值以便上层计算

图论

递归,深度优先搜索 dfs(深搜三部曲

  1. 确认递归函数,参数
  2. 确认终止条件
  3. 处理目前搜索节点出发的路径

队列,广度优先搜索 bfs(层序遍历)

2024.5.20


200 岛屿数量

 DFS,BFS,并查集,基础题目

  • 目标是找到矩阵中 “岛屿的数量” ,上下左右相连的 1 都被认为是连续岛屿。
  • dfs方法: 设目前指针指向一个岛屿中的某一点 (i, j),寻找包括此点的岛屿边界。
    • 从 (i, j) 向此点的上下左右 (i+1,j),(i-1,j),(i,j+1),(i,j-1) 做深度搜索。
    • 终止条件:
      • (i, j) 越过矩阵边界;
      • grid[i][j] == 0,代表此分支已越过岛屿边界。
    • 搜索岛屿的同时,执行 grid[i][j] = '0',即将岛屿所有节点删除,以免之后重复搜索相同岛屿。
  • 主循环
    • 遍历整个矩阵,当遇到 grid[i][j] == '1' 时,从此点开始做深度优先搜索 dfs,岛屿数 count + 1 且在深度优先搜索中删除此岛屿。
  • 最终返回岛屿数 count 即可。

2024.5.21


994 腐烂的橘子

就是求腐烂橘子到所有新鲜橘子的最短路径    采用层序遍历 bfs,一层一层进行污染

2024.5.24


207 课程表

208 实现Trie(前缀树)

 回溯

回溯三部曲:

  • 递归函数参数
  • 递归函数终止条件
  • 单层搜索的逻辑
46 全排列

回溯法:一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解被确认不是一个解(或者至少不是最后一个解),回溯算法会通过在上一步进行一些变化抛弃该解,即回溯并且再次尝试。

2025.5.25


78 子集 
  • 时间复杂度:O(n×2^n)。一共 2^n个状态,每种状态需要 O(n)的时间来构造子集。
  • 空间复杂度:O(n)。临时数组 t 的空间代价是 O(n),递归时栈空间的代价为 O(n)。

 17 电话号码的字母组合

首先创建一个字符串列表作为输出,用哈希表存储每个数字对应的字母,创建StringBuffer类型的字符串不断加入字母;从下标为0开始,找到对应的数字,从哈希表中取出对应的字母字符串,并记录字符串长度,对于每个字母依次进行加入操作,并在这个情况下继续下一个位置;递归之后进行回溯删去这个字母;当索引等于digits数字字符串的长度时,完成一个字符串组合,并加入列表中。

2024.6.3


39 组合总和

画树形图,深度优先遍历,完加入这个数遍历后再移除进行回溯

 22 括号生成

2024.6.4 


79 单词搜索

深度优先搜索+剪枝

 131 分割回文串

切割问题和组合问题的回溯过程差不多

 N皇后困难题先不写了,之后再补。

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值