This article is participating in the “Java Theme Month – Java brush questions clock”, see < activity links > for more details.
【Java brush questions punch card 】 Brushing questions is much better than playing games, and the sense of achievement is getting stronger and stronger. I insist on brushing several questions every day, exercising for 30 minutes every day, waiting for 8-block abs and waiting for offers from big factories.
😄
Then do it! This column is all about the topic of binary trees, I will start from the shallow to the deep, step by step, brush questions is such a need for continuous memory – Ebbinghaus memory method 2121112. The content of binary tree is not much, but it is necessary for every programmer to understand the red black tree, B+ tree, LSM tree are very helpful and so on
Leveldb and Rocksdb implemented by WAL+ Lsm-tree
B + tree mysql
(HBASE) – LSM-Tree converts random write to sequential write, supports multiple layers compaction and lookup, and supports write amplification and read amplification
TokuDB –Fractal Tree
There’s more to discover.
- Sequential traversal in a binary tree – iteration, recursion
- Binary tree before sequential traversal – iteration, recursion
- Binary tree after sequential traversal – iteration, recursion
- Binary tree sequence traversal – iteration, recursion
- Maximum depth of binary tree – iterative, recursive
- Symmetric binary tree of binary tree – iteration, recursion
- Binary tree path sum – iterative, recursive
- Construct binary tree – iteration and recursion by traversing sequence from middle order to back order
Leecode 236. The most recent common ancestor of binary trees
Given a binary tree, find the nearest common ancestor of the two specified nodes in the tree.
The definition of the nearest common ancestor in Baidu Encyclopedia is as follows: “For two nodes P and Q with root tree T, the nearest common ancestor is expressed as a node X, which satisfies that X is the ancestor of P and Q and the depth of X is as large as possible (a node can also be its own ancestor).
Example 1:
Input: root = [3,5,1,6,2,0,8, null, null, 7, 4], p = 5, q = 1
Output: 3
The most recent common ancestor of nodes 5 and 1 is node 3.
Example 2:
Input: root = [3,5,1,6,2,0,8, null, null, 7, 4], p = 5, q = 4
Output: 5
The most recent common ancestor of nodes 5 and 4 is node 5. Because by definition the nearest common ancestor node can be the node itself.
Reference code
Define a tree
class TreeNode {
int val; / / head node
TreeNode left; / / the left subtree
TreeNode right; / / right subtree
TreeNode(intx) { val = x; }}// Test method
public static void main(String[] args) {
TreeNode treeNode = new TreeNode(1);
treeNode.left = new TreeNode(2);
treeNode.right = new TreeNode(3);
System.out.println("XXXX result =" + preorderTraversal(treeNode));
}
Copy the code
- You know, this is a tree, it’s just represented as an array
Let’s take this tree as an example
Key points:
-
Recursive export
-
Look in the left subtree of that node
-
Go to the right subtree of that node
-
It indicates that the node is the most recent common ancestor
-
Not on the left subtree, which means it’s on the right subtree
-
If not on the right subtree, it’s on the left subtree
public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// Recursive exit
if (root == null || root == p || root == q) {
return root;
}
// Go to the left subtree of the node
TreeNode left = lowestCommonAncestor(root.left, p, q);
// Go to the right subtree of the node
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left == null) {
// If there is no left subtree, it is on the right subtree
return right;
} else if (right == null) {
// If the right subtree does not exist, it is on the left subtree
return left;
}
// Left and right, indicating that the node is the nearest common ancestor
return root;
}
Copy the code
The iterative version
The core and recursion are pretty much the same.
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
parent := map[int]*TreeNode{}
visited := map[int]bool{}
var dfs func(*TreeNode)
dfs = func(r *TreeNode) {
if r == nil {
return
}
ifr.Left ! = nil { parent[r.Left.Val] =r
dfs(r.Left)
}
if r.Right != nil {
parent[r.Right.Val] = r
dfs(r.Right)}}dfs(root)
for p != nil {
visited[p.Val] = true
p = parent[p.Val]
}
forq ! = nil {if visited[q.Val] {
return q
}
q = parent[q.Val]
}
return nil
}
Copy the code
Thank you for reading this, if this article is well written and if you feel there is something to it
Ask for a thumbs up 👍 ask for attention ❤️ ask for share 👥 for 8 abs I really very useful!!
If there are any mistakes in this blog, please comment, thank you very much! ❤ ️ ❤ ️ ❤ ️ ❤ ️