问题描述
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5
For example, the lowest common ancestor (LCA) of nodes 2
and 8
is 6
. Another example is LCA of nodes 2
and 4
is 2
, since a node can be a descendant of itself according to the LCA definition.
原问题链接:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/
问题分析
这个问题相对很简单,只要知道二叉搜索树的都知道,它的一个基本特性就是 任何一个节点,它比自己的左子树值大,同时比自己的右子树小。所以如果要给定树上面两个节点,并查找它最低公共父节点的话,可以这样来考虑:
首先考虑最低公共父节点,既然是最低的公共父节点,必然这个节点是如下几种情况,
1. 存在一个节点,给给定的两个节点分别在它的左右子树中。这种情况最常见,如下图:
在该图中,我们选择的节点是6和9,它们最低公共父节点是8.
2. 一个节点是另外一个节点的父节点,这种情况我们也可以称那个处于父节点位置的节点为它们的最低公共父节点,如下图:
在该图中,5节点是6节点的父节点,它也就是它们的最低公共父节点。
既然我们要找的是两个节点的最低公共父节点,所以它们都有一个比较有意思的特征,就是该最低公共父节点一定满足 m.val >= p.val && m.val <= q.val,假设p, q表示我们给定的两个节点。为什么不是m节点的父节点呢?因为m节点必然是它父节点的左子节点或者右子节点。这样它的父节点相对节点p, q就不满足上述的关系了。
既然定义好了这个特性我们就来进一步分析怎么来查找这个节点。我们首先能够访问的节点是根节点root。对于该节点来说,如果p, q两个节点的值都小于它的值,则说明这两个节点在它的左子树,我们可以到它的左子树做进一步的查找。如果p, q两个节点的值都大于它的值,则说明应该去它的右子树查找。而对于其他的情况则说明我们找到了符合条件的节点。这样我们可以得到如下的代码:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q); if(root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q); return root; } }
非常简单,没什么好说的。当然,我们也可以写一个非递归版的实现:
public 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 return root; } } }
总结
这个问题总的来说还是比较好找思路。重点在于它的最低父节点满足m.val > p.val && m.val < q.val。而且它们互为充分必要条件。所以我们要找这个节点的时候只需要根据当前节点和两个节点的值比较去选择下一步去哪个子树就可以了。当然,从这个问题衍生出来的问题还有更复杂的,比如针对普通二叉树的情况,它不是二叉搜索树,那么这种情况该怎么处理呢?我们在后面的文章中继续讨论。
相关推荐
java java_leetcode题解之Lowest Common Ancestor of a Binary Tree.java
c c语言_leetcode题解之0236_lowest_common_ancestor_of_a_binary_tree
c c语言_leetcode题解之0235_lowest_common_ancestor_of_a_binary_search
4. **树结构**:如“二叉树的最近公共祖先”(Lowest Common Ancestor of a Binary Tree),需要找到给定节点的最近公共祖先。 5. **动态规划**:如“最长连续序列”(Longest Consecutive Sequence),要求找到一个...
"二叉树的最近公共祖先"(Lowest Common Ancestor of a Binary Tree)可以用递归或迭代的方法解决。 5. **图**:图问题可能涉及到深度优先搜索(DFS)、广度优先搜索(BFS)等。例如,"最短路径"(Shortest Path in...
问题235:“最近的公共祖先(Lowest Common Ancestor of a Binary Search Tree)” 这是一个关于二叉搜索树的问题。在二叉搜索树中,每个节点的值都大于其左子树中的所有节点值,小于其右子树中的所有节点值。这个问题...
例如,"二叉树的最近公共祖先"(Lowest Common Ancestor of a Binary Tree)题目,需要理解深度优先搜索或层次遍历的方法。 高级算法: 高级算法通常涉及到更深层次的思考和优化,如位运算、贪心策略、分治法等。...
比如"二叉树的最近公共祖先"(Lowest Common Ancestor of a Binary Tree)需要掌握树的遍历策略,而"有效的井字游戏"(Valid Tic-Tac-Toe)则需要理解博弈论的Nim游戏规则。 每道题的Markdown文件通常包含以下几个...
12. **Lowest Common Ancestor of a Binary Search Tree**:二叉搜索树的最近公共祖先。利用二叉搜索树的性质,可以有效地向上遍历找到最近公共祖先。 13. **Product of Array Except Self**:不包含自身的数组乘积...
5. **二叉树与图**:二叉树题目如"Binary Tree Inorder Traversal"(二叉树的中序遍历)和"Lowest Common Ancestor of a Binary Tree"(二叉树的最近公共祖先),图题目如"Shortest Path in Bidirectional Graph"...
Lowest Common Ancestor of a Binary Search Tree等。通过解决这些题目,你可以加深对二叉树的理解,并提升解决问题的能力。 总结,Java中的二叉树题目不仅要求对数据结构有深入理解,还需要灵活运用算法。不断...
要在控制台中运行特定问题,请转至文件test,将调用添加到测试函数( test() ),然后在控制台node <problem> (例如, node LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js )。 Leetcode问题 名称...
leetcode 和 oj LeetCode 解决方案 Java 版 Leetcode 问题分类 细绳 8 字符串到整数 (atoi) 14 ...oj_102_binary_tree_level_order ...oj_236_lowest_common_ancestor_of_bt / notes.md SRC /溶液/ oj
lru缓存leetcode 力码 如果你在这里找不到答案,你可以移到 1. BFS/拓扑/图 2.联合查找 3. 二分查找 4. 动态规划 Double Sequence Problem (双序列) Knapsack Problem (背包问题) --- Binary Lifting for LCA...
2. 树形结构:树相关的题目如“Binary Tree Inorder Traversal”(二叉树的中序遍历)和“Lowest Common Ancestor of a Binary Tree”(二叉树的最近公共祖先)等,要求对二叉树的遍历和搜索有深入理解。 3. 排序与...
2. 二叉树:例如“Lowest Common Ancestor of a Binary Tree”涉及到二叉树的遍历和节点查找。 3. 图论:如“Course Schedule II”可能涉及拓扑排序和深度优先搜索。 4. 字符串处理:如“Valid Palindrome II”要求...
如“二叉树的最近公共祖先”(Lowest Common Ancestor of a Binary Tree)和“拓扑排序”(Topological Sort)。 8. **动态规划**:动态规划用于解决具有重叠子问题和最优子结构的问题,如“背包问题”(Knapsack ...
例如,“二叉树的最近公共祖先”(Lowest Common Ancestor of a Binary Tree)问题,要求找到二叉树中两个节点的最近公共祖先。 8. **动态规划**:这是一种优化问题解决的策略,常用于解决背包问题、最长公共子序列...
在给定的文件中,我们讨论的是一个与计算机科学相关的编程问题,具体是关于二叉搜索树(Binary Search Tree, BST)的最近公共祖先(Lowest Common Ancestor, LCA)问题。这个问题来源于LeetCode的一个挑战,其目标是...