Leetcode刷题笔记Day10:二叉树Ⅴ

52 阅读2分钟

二叉搜索树的修改与构造

二叉搜索树的最近公共祖先

  • 力扣题目链接
  • 顺序无所谓,如果节点的数值在目标区间就是最近公共祖先
  • 直接迭代法!
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, 
                               TreeNode* q) {
    while(root)
        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;
    return nullptr;
}

二叉搜索树中的插入操作

TreeNode* insertIntoBST(TreeNode* root, int val) {
    if(root==nullptr){
        TreeNode* node=new TreeNode(val);
        return node;
    }
    if(root->val>val)
        root->left=insertIntoBST(root->left, val);
    else root->right=insertIntoBST(root->right, val);
    return root;
}

删除二叉搜索树中的节点

TreeNode* deleteNode(TreeNode* root, int key) {
    // 第一种情况:没找到删除的节点,遍历到空节点直接返回了
    if(root==nullptr) return root;
    else if(root->val==key){
        // 第二种情况:左右孩子都为空(叶子节点),直接删除节点
        if(!root->left && !root->right) {
            delete root; return nullptr;
        }
        TreeNode* retNode;
        if(!root->left) retNode=root->right;
        else if(!root->right) retNode=root->left;
        else{
            auto cur=root->right;
            // 找右子树最左面的节点
            while(cur->left!=nullptr) cur=cur->left;
            cur->left=root->left;
            retNode=root->right;
        }
        delete root;
        return retNode;
    }
    else if(root->val>key)
        root->left=deleteNode(root->left, key);
    else root->right=deleteNode(root->right, key);
    return root;
}

修剪二叉搜索树

TreeNode* trimBST(TreeNode* root, int low, int high) {
    if(root==nullptr) return root;
    if(root->val<low)
        return trimBST(root->right, low, high);
    else if(root->val>high)
        return trimBST(root->left, low, high);
    root->left=trimBST(root->left, low, high);
    root->right=trimBST(root->right, low, high);
    return root;
}

将有序数组转换为二叉搜索树

TreeNode* traversal(vector<int>& nums, int left, int right){
    if(left>right) return nullptr;
    // 如果数组长度为偶数,中间位置有两个元素,取靠左边的
    int mid=left+(right-left)/2;
    TreeNode* root=new TreeNode(nums[mid]);
    root->left=traversal(nums, left, mid-1);
    root->right=traversal(nums, mid+1, right);
    return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
    if(nums.empty()) return nullptr;
    TreeNode* root=traversal(nums, 0, nums.size()-1);
    return root;
}

把二叉搜索树转换为累加树

  • 力扣题目链接
  • 递归:中序,双指针操作累加,注意是反中序遍历!
int pre=0; // 记录前一个节点的数值
void traversal(TreeNode* root){ // 右中左遍历
    if(root==nullptr) return;
    traversal(root->right);
    root->val+=pre;
    pre=root->val;
    traversal(root->left);
}
TreeNode* convertBST(TreeNode* root) {
    traversal(root);
    return root;
}

二叉树总结

  • 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
  • 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
  • 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。

参考资料

[1] 代码随想录

[2] Leetcode题解