一、 数组类型解题方法一:二分法
二、数组类型解题方法二:双指针法
三、数组类型解题方法三:滑动窗口
四、数组类型解题方法四:模拟
五、链表篇之链表的基础操作和经典题目
六、哈希表篇之经典题目
七、字符串篇之经典题目
八、字符串篇之 KMP
九、解题方法:双指针
十、栈与队列篇之经典题目
十 一、栈与队列篇之 top-K 问题
十 二、二叉树篇之二叉树的前中后序遍历
十 三、二叉树篇之二叉树的层序遍历及相关题目
十 四、二叉树篇之二叉树的属性相关题目
十 五、 二叉树篇之二叉搜索树的
十 六、 二叉树篇之二叉搜索树的属性
更新中 … …
刷题路线来自 :代码随想录
Leetcode 链接
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return dfs(root, p, q);
}
public TreeNode dfs (TreeNode root, TreeNode p, TreeNode q) {
// 终止条件,找到就返回找到的结点,没找到就返回 null
if (root == null || root == p || root == q) {
return root;
}
// 后序遍历
// 接收到左右子树返回的结果
TreeNode left = dfs(root.left, p, q);
TreeNode right = dfs(root.right, p ,q);
// 向上回溯
// 左右各一个,返回当前根节点
if (left != null && right != null) return root;
// 一边为 null ,一边找到,返回找到的结点
if (left == null && right != null) return right;
if (left != null && right == null) return left;
// 左右都为 null, 都每找到返回 null
return null;
}
}
Leetcode 链接
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
题解:
方式一:递归
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return dfs(root, p, q);
}
public TreeNode dfs(TreeNode root, TreeNode p, TreeNode q) {
if (root.val > p.val && root.val > q.val) {
// 根节点值大,p q 结点肯定在左边,返回向左递归的结果
return dfs(root.left, p, q);
}
if (root.val < p.val && root.val <q.val) {
// 根节点值小,p q 结点肯定在左边,返回向右递归的结果
return dfs(root.right, p ,q);
}
// 根节点在 p q 中间,或者根结点等于 p q 其中一个,就是 p q 的最近公共祖先
return root;
}
}
方式二:迭代
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while (true) {
if (root.val > p.val && root.val > q.val) {
// 根结点大,向左子树遍历
root = root.left;
} else if (root.val < p.val && root.val < q.val) {
// 根结点小,向右子树遍历
root = root.right;
} else {
// 根节点在中间,或者根结点等于 p q 其中一个
break;
}
}
return root;
}
}