LeetCodeCampsDay18二叉树part06
LeetCodeCampsDay18二叉树part06
…
236. 二叉树的最近公共祖先
https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:
1 | 输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 |
示例 2:
1 | 输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 |
示例 3:
1 | 输入:root = [1,2], p = 1, q = 2 |
提示:
- 树中节点数目在范围
[2, 105]
内。 -109 <= Node.val <= 109
- 所有
Node.val
互不相同
。 p != q
p
和q
均存在于给定的二叉树中。
递归思路
- 输入输出:输入node, q, p; 输出公共节点
- 终止条件:当前节点为空返回None,当前节点为p或q则返回当前节点
- 单层逻辑:需要先搜索左、右子树中是否存在p&q
- 如果左、右子树有p&q(即左、右子树不为None),则当前node为公共节点;
- 下一步是需要考虑,如何将公共节点传到最上层:这里需要解释下,假设[10,1,7,2,3](其中2,3为p&q),假设当前节点为10,对10来说,1(左子树)返回值是None(因为不存在p或q),而7(右子树)返回值为7(不为空),说明7就是q&p的最近公共祖先;10只需要将7返回,即if leftNode and not rightNode: return leftNode
递归代码
1 | # Definition for a binary tree node. |
235. 二叉搜索树的最近公共祖先
https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
1 | 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 |
示例 2:
1 | 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 |
说明:
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉搜索树中。
递归思路
- 本题是BST,可以利用它的特性;如果node大于q.val且大于p.val,则需要向左遍历,在左子树中找公共祖先节点;如果node小于q.val且小于p.val,需要向右遍历,在右子树中找公共祖先节点;否则,直接返回node, node一定为p和q的公共祖先节点
代码
- 时间复杂度O(N)
- 空间复杂度O(H)
1 | # Definition for a binary tree node. |
530. 二叉搜索树的最小绝对差
https://leetcode.cn/problems/minimum-absolute-difference-in-bst/
给你一个二叉搜索树的根节点 root
,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
1 | 输入:root = [4,2,6,1,3] |
示例 2:
1 | 输入:root = [1,0,48,null,null,12,49] |
提示:
- 树中节点的数目范围是
[2, 104]
0 <= Node.val <= 105
迭代思路
- 本题和
98. 验证二叉搜索树
很像,都可以靠中序遍历,并且判断相邻两位元素的值(差)来解决;这需要用到BST特性,即左节点小于等于root,root小于等于右节点
迭代代码
1 | # Definition for a binary tree node. |
501. 二叉搜索树中的众数
https://leetcode.cn/problems/find-mode-in-binary-search-tree/
给你一个含重复值的二叉搜索树(BST)的根节点 root
,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
示例 1:
1 | 输入:root = [1,null,2,2] |
示例 2:
1 | 输入:root = [0] |
提示:
- 树中节点的数目在范围
[1, 104]
内 -105 <= Node.val <= 105
**进阶:**你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
迭代思路
- 用中序遍历,关键是在「中间节点的操作」,本题和
530二叉搜索树的最小绝对差
以及98. 验证二叉搜索树
相似,需要引入pre节点,判断前后两个元素是否相等,如果相等则将count+1,如果不相等则重置count为1。随后判断count是否等于MaxFreq,如果是,则将元素添加到res里;如果count大于MaxFreq,则将res清空并且将元素添加到res里,并设置MaxFreq等于count - 本题如果只有一个众数,那会相对简直一些,只要一直记录count最大的元素就好,也不用对res清空
迭代代码
- 时间复杂度O(N)
- 空间复杂度O(H) – 主要是stack占用的
1 | # Definition for a binary tree node. |
递归代码
- 时间复杂度O(N)
- 空间复杂度O(H) – 最好O(logN)最坏O(N)
1 | def traverse(self, node) -> List[int]: |
思考
如果本题不是BST而是普通树,可以先做遍历(中/前/后/层序都行),再进行排序,排序时按频率将最高频率的添加到res里