LeetCode 235. 二叉搜索树的最近公共祖先
解题思路
二叉搜索树满足左子树的所有值小于中间结点的值,右子树的所有值大于中间结点的值。所以如果中间结点是p、q的公共祖先,中间结点的数值一定是在这个区间内的。从上往下递归遍历,第一次遇到符合条件的结点值,就是我们所要找的最近公共祖先。
由于不知道p 、q结点值的大小,所以可以先进行判断,p对应val值较小的结点。
代码解析
/**
* 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 {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(p->val > q->val)
{
swap(p, q);
}
// return p;
if(root->val > p->val && root->val < q->val)
{
return root;
}
if(root->val < p->val)
root = lowestCommonAncestor(root->right, p, q);
if(root->val > q->val)
root = lowestCommonAncestor(root->left, p, q);
return root;
}
};
LeetCode 701. 二叉搜索树的插入操作
解题思路
本题的关键是遇到空结点就插入结点就可以。
递归三部曲:
- 确定函数参数及返回值: 参数是根结点指针以及要插入的元素,返回值是新加入的结点;
- 确定终止条件: 当遍历的结点为null时,就是需要插入结点的位置,并把插入的结点返回;
- 单层递归的逻辑: 由于是二叉搜索树,不需要遍历整颗树。根据插入元素的数值决定递归的方向
if (root->val > val) root->left = insertIntoBST(root->left, val);
if (root->val < val) root->right = insertIntoBST(root->right, val);
return root;
如何通过递归函数返回值完成新加入结点的父子关系赋值操作: 下一层将加入结点返回,本层用root->left 或者 root->right 接住。
代码解析
/**
* 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) {
if(root == nullptr)
return new TreeNode(val);
// 寻找指定位置
if(root->val >val)
root->left = insertIntoBST(root->left, val);
else
root->right = insertIntoBST(root->right, val);
return root;
}
};
LeetCode 235. 删除二叉搜索树的结点
解题思路
相比上一道题目,本题复杂在于删除一个结点可能要调整二叉树的结构。遍历过程中首先要找到这个结点,然后根据这个结点的左、右孩子情况进行讨论。
- 结点为空,说明没找到,返回空结点;
- 该结点是叶子结点,直接返回null 给其父结点;
- 该结点的左孩子不为空,右孩子为空,删除结点,左孩子补位,返回左孩子给其父结点;
- 该结点的左孩子为空,右孩子不为空,删除结点,右孩子补位,返回右孩子给其父结点;
- 该结点的左、右孩子都不为空,将删除结点的左子树 放到删除结点的右子树的左边面结点的左孩子上,返回删除结点的右孩子;
代码解析
/**
* 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) {
if(root == nullptr)
return nullptr;
if(root->val ==key)
{
if(root->left !=nullptr && root->right == nullptr)
{
return root->left;
}
else if(root->left == nullptr && root->right!=nullptr)
{
return root->right;
}
else if(root->left !=nullptr && root->right !=nullptr)
{
TreeNode * cur = root->right;
while(cur->left !=nullptr)
{
cur = cur->left;
}
cur->left = root->left;
return root->right;
}
else
{
return nullptr;
}
}
if(key < root->val)
root->left = deleteNode(root->left, key);
if(key > root->val)
root->right = deleteNode(root->right, key);
return root;
}
};