Journey of LeetCode|DAY 19
Preface
This is a new day to continue my binary tree journey.
Learn something new and keep reviewing what I learnt before.
1. Lowest Common Ancestor of a Binary Search Tree
LeetCode Link: 235. Lowest Common Ancestor of a Binary Search Tree
Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Analysis and Solution
Recursion
LeetCode C++ as followings Recursion
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
TreeNode* traversal(TreeNode* cur, TreeNode* p, TreeNode* q) {//recursion function with current node and target p q as parameters
if (cur == NULL) return cur;//terminate condition
// middle tree
if (cur->val > p->val && cur->val > q->val) { // left tree; according to the nature of binary search tree.left tree < root
TreeNode* left = traversal(cur->left, p, q);//recursion left tree
if (left != NULL) {
return left;//the result is what we want
}
}
if (cur->val < p->val && cur->val < q->val) { // right tree; according to the nature of binary search tree.right tree < root
TreeNode* right = traversal(cur->right, p, q);//recursion right tree
if (right != NULL) {
return right;//result is what we want
}
}
return cur;//result
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {//main function
return traversal(root, p, q);//return result
}
};
2. Insert into a Binary Search Tree
LeetCode Link: 701. Insert into a Binary Search Tree
You are given the root node of a binary search tree (BST) and a value to insert into the tree. Return the root node of the BST after the insertion. It is guaranteed that the new value does not exist in the original BST.
Notice that there may exist multiple valid ways for the insertion, as long as the tree remains a BST after insertion. You can return any of them.
Analysis and Solution
Recursion
LeetCode C++ as followings Recursion
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {//main function with root and target value as parameters
if (root == NULL) {
TreeNode* node = new TreeNode(val);//build a new node
return node;//terminate condition;
}
if (root->val > val) root->left = insertIntoBST(root->left, val);//recursion left tree if target value < root
if (root->val < val) root->right = insertIntoBST(root->right, val);//recursion right tree if target value > root
return root;
}
};
3. Delete Node in a BST
LeetCode Link: 450. Delete Node in a BST
Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.
Basically, the deletion can be divided into two stages:
Search for a node to remove.
If the node is found, delete the node.
Analysis and Solution
Recursion
LeetCode C++ as followings Recursion
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {//recursion function with root and key as parameters
if (root == nullptr) return root; // case 0:directly return when cannot find the key; traverse until null node
if (root->val == key) {
// case 1:left and right tree all are null; delete node and return null as root
if (root->left == nullptr && root->right == nullptr) {
//release memory
delete root;
return nullptr;
}
// case 2:left tree is null and right tree isnot; delete node and right node make a complementary, return right node as root
else if (root->left == nullptr) {
auto retNode = root->right;
// release memory
delete root;
return retNode;
}
// case 3:right tree is null and left tree isnot; delete node and left node make a complementary, return left node as root
else if (root->right == nullptr) {
auto retNode = root->left;
//release memory
delete root;
return retNode;
}
// case 4:left and right tree are not null; move the left tree that node was deleted to the site belongs to the left child of leftest node of right tree that node was deleted
// return right child node of deleted node as new root
else {
TreeNode* cur = root->right; // To find leftmost node of the right tree
while(cur->left != nullptr) {
cur = cur->left;
}
cur->left = root->left; // put the left subtree of the deleted node(root) in the position of right tree of current
TreeNode* tmp = root; // save the node of root; delete it later
root = root->right; // return right child of the root as new root
delete tmp; // release memory
return root;
}
}
if (root->val > key) root->left = deleteNode(root->left, key);//recursion left tree
if (root->val < key) root->right = deleteNode(root->right, key);//recursion right tree
return root;
}
};