LeetCode Day21 二叉搜索树

这篇博客介绍了如何在二叉搜索树中进行插入、删除、修剪和转换操作。讨论了701题的插入操作,450题的删除操作,669题的修剪操作,108题的有序数组转二叉树,以及538题的累加树转换。每个操作都详细阐述了解题思路并提供了相应的代码实现。
摘要由CSDN通过智能技术生成

701 二叉搜索树中的插入操作

题目

将给定值插入到二叉搜索树中,返回插入后二叉搜索树的根节点,树在插入后仍然要保持为二叉搜索树。

思路

递归来解决,结束条件为当前节点为空,则应该在这个位置插入节点。每次递归,可以根据插入值的大小来决定递归方向。新加入节点的值可以赋给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) {
            TreeNode* node = new TreeNode(val);
            return node;
        }
        if(root->val > val)
            root->left = insertIntoBST(root->left,val);
        else if(root->val < val)
            root->right = insertIntoBST(root->right,val);
        return root;
    }
};

450 删除二叉搜索树中的节点

题目

删除二叉搜索树中值为key的节点,保证二叉搜索树的性质不变。

思路

删除节点需要对二叉搜索树的结构进行调整,首先如果没有找到值为key的节点,遍历到空节点直接返回即可。找到值为key的节点,先考虑它的子节点为空的情况:
①左孩子为空,右孩子不空,则返回右孩子;
②左孩子非空,右孩子空,则返回左孩子;
③左右孩子都空,则返回空;
④左右都不空,把左孩子节点添加到右孩子的最左边的叶子节点的左孩子处,返回右孩子。

代码

/**
 * 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)
            return nullptr;
        if(root->val == key) {
            if(!root->left)
                return root->right;
            else if(!root->right)
                return root->left;
            else if(!root->left && !root->right)
                return nullptr;
            else {
                TreeNode* temp = root->right;
                while(temp->left) 
                    temp = temp->left;
                temp->left = root->left;
                temp = root;
                root = root->right;
                delete temp;
            }
        }
        if(root->val > key)
            root->left = deleteNode(root->left,key);
        if(root->val < key)
            root->right = deleteNode(root->right,key);
        return root;
    }
};

669 修剪二叉搜索树

题目

给定范围[low,high],修剪二叉搜索树,使所有节点的值在此范围内。

思路

递归来解决,终止条件为当当前节点为空时,返回空。
单次递归,当节点值小于low或大于high时,则应该递归右子树或递归左子树,返回符合条件的左右子树头节点;当节点值满足条件时,递归左子树和右子树。

代码

/**
 * 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* trimBST(TreeNode* root, int low, int high) {
        if(!root)
            return nullptr;
        if(root->val < low)
            root = trimBST(root->right,low,high);
        else if(root->val > high)
            root = trimBST(root->left,low,high);
        else {
            root->left = trimBST(root->left,low,high);
            root->right = trimBST(root->right,low,high);
        }
        return root;
    }
};

108 将有序数组转换为二叉树

思路

将有序数组的中间元素作为头结点,以头结点为边界再分为左右两个数组,递归左右数组,因为每次都是以中间元素为头结点,左右元素个数差不会超过1,这样转换成的二叉树本身就是平衡的,类似于二分。

代码

/**
 * 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* 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) {
        return traversal(nums,0,nums.size() - 1);
    }
};

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

思路

因为是二叉搜索树,最右边元素最大,所以累加应该是按照从右到左的顺序进行,相当于是右中左累加,就是中序遍历反过来,用一个值pre来记录上一个节点的值,当前节点的值+=pre,先遍历右子树,更新中节点的值,再遍历左子树。

代码

/**
 * 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:
    int pre;
    void traversal(TreeNode* cur) {
        if(!cur)
            return;
        traversal(cur->right);
        cur->val += pre;
        pre = cur->val;
        traversal(cur->left);
    }
    TreeNode* convertBST(TreeNode* root) {
        traversal(root);
        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值