Skip to content

Oj 题目 ​

本文章是收录有问题的Oj题目,

这里有问题是指做过了但是第二次做依然没有思路的题目

List ​

给定⼀个链表,判断链表中是否有环 ​

使用快慢指针,一个速度为 2 另一个速度为 1,只要判断它们两是否相遇即可判断是否有环

问题:速度为什么一个是 2,一个是 1 ?一个是 3,一个是 4 行不行?

原因:它们之间的差为 1,只要满足这个条件,就一定可以追上,如果相差不是 1,就可能会跳过甚至永远不会相遇

LC142. 环形链表 II ​

这个题目和前面的 给定⼀个链表,判断链表中是否有环 很像,只不过它是从判断这个列表是不是环形列表改为获取它的下标了

思路:
9999-OJ题目-LC142.环形链表II
9999-OJ题目-LC142.环形链表II
  1. 定义三个变量:
    • a: 表示环状列表的下标左侧那一段路程
    • b: 环状列表的下标到快慢双指针之间的路程
    • L: 环状列表一圈的长度
  2. 快指针速度是慢指针的两倍,慢指针的路程是 a + b,因此快指针的路程是 2 * (a + b)(假设起始位置一样)
  3. 又因为快指针减去慢指针的路程是 L 的整数倍,因此 a + b = n * L 既 a = (n - 1) * L + (L - b)
  4. L - b 表示的就是剩余圈数的长度,因此第二次循环中,第一个从 head 出发,走 a 的距离,第二个从 slow(fast) 出发,走剩余的长度+若干圈,它们就会在入口处相遇

Tree ​

⼆叉树的构建及遍历 ​

使用递归的思路经行创建,通过外部 index 下标来获取字符

递归终止条件: index 获取到的字符是 # 递归过程: index 获取到的字符不是 #,创建根节点 root ,然后再通过 createTree 这个方法递归, 分别创建左子树与右子树,最后返回 root

就以 abc##de#g##f### 为例, a 就是根节点,左节点就是 bc##de#g##f##,右节点是 #

左节点的根节点是 b,它的左节点是 c## 它的右节点是 de#g##f##。以此类推……

二叉树的最近公共祖先 ​

方法1:

  1. 获取到对应的节点到根节点的链表
  2. 然后通过寻找链表公共节点来获取到最近公共祖先(速度太慢了,于是看看视频是怎么写的)

方法2:

  1. p/q 是公共祖先
    1. root == q || root == p 那么就返回 root
    2. 不满足上诉条件时候,通过递归来获取
  2. p/q 在 root 两边
    1. 通过递归在左右两边同时找到相关的节点,直接返回 root
    2. 找不到直接递归即可

二叉树的前序遍历(非递归) ​

递归的方法很简单,这里就不说明了,这里主要说明的通过迭代的方法

迭代方法本质是把递归中系统自动开栈变成手动入栈的过程

把递归变成迭代需要明白 3 个要素

问题答案
什么时候入栈?等效于递归中进入方法的时候
为什么要入栈,入栈的目的主要是什么?为了可以恢复现场,记录下此时的状态,类似递归中的“归”的过程中,依然可以获取到当时的上下文
入栈怎么入?递归是顺序来,而入栈的时候由于栈的性质,是需要反过来。比如前序遍历中,递归是先左再右,而迭代中入栈是先右再左

二叉树的中序遍历(非递归) ​

递归的方法很简单,这里就不说明了,这里主要说明的通过迭代的方法

  1. 用 cur 来表示当前的节点
  2. cur 不为空,那么一直添加左子树,然后 cur = cur.left,将 cur 指向左子树
  3. cur 为空,说明左子树已经遍历完,就可以遍历右子树了,此时可以弹出根节点,并添加再 list 中,执行 cur = cur.right,把 cur 指向右子树
  4. 上诉为一次循环(遍历左子树),只需要再外层添加判断 stack 是否为空即可

二叉树的后序遍历(非递归) ​

大体的思路与 二叉树的中序遍历 一样,只是在左子树遍历完后处理的方式有所不同

  1. 是执行 stack.peek() 而不是 stack.pop(),因为不确定有没有遍历到右子树
  2. 如果右子树为空 或者 右子树已经遍历过,那么就直接 pop() 弹出,打印根节点,然后记录打印的节点
  3. 如果右子树不为空并且没有遍历过,那么将 cur 指向右子树,然后重新遍历

Set 与 Map ​

随机链表的复制 ​

通过 Map 这个数据结构来解决

  1. 遍历原数据,构建 Map, Map 的 key 是旧节点下标, val 是新节点下标
  2. 此时 map.get(node) 可以获取到旧节点对应新节点的下标, 那么就可以通过 map.get(cur.next) 与 map.get(cur.random) 获取到对应新节点的 next 与 random
  3. 最后返回新节点的头节点即可
用例 1/1
步骤: 0 / 0

当前动作:等待输入...