五月集训(第20天)—二叉搜索树

二叉搜索树

1. 700. 二叉搜索树中的搜索

    思路:
        类似于二分查找
        (1)val < root->val,去左子树查找
        (1)val > root->val,去右子树查找
        (1)val == root->val,返回该结点,即为目标子树的根节点

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if (root == nullptr) return nullptr;
        /* 只需要将找到的子树根节点返回即可 */
        if (val < root->val) return searchBST(root->left, val);
        else if (val > root->val) return searchBST(root->right, val);
        
        return root;
    }
};

2. 230. 二叉搜索树中第K小的元素

    思路:
        利用二叉搜索树的性质,root->left->val< root->val< root->right->val,中序遍历得到的结果是升序排列的,则在中序遍历结果的基础上,记录一个k的值,从最小值开始--k,直到k == 0时,找到了第k小的元素。

class Solution {
    int ans = 0;
    int kk;	/* 用全局遍历,实时修改k的值 */

    void dfs(TreeNode *root) {
        if (root) {
            dfs(root->left);

            if (--kk == 0) ans = root->val;

            dfs(root->right);
        }
    }
public:
    int kthSmallest(TreeNode* root, int k) {
        kk = k;
        dfs(root);
        return ans;
    }
};

利用传引用实时修改k的值

class Solution {
    int ans = 0;

    void dfs(TreeNode *root, int &k) {
        if (root) {
            dfs(root->left, k);

            if (--k == 0) ans = root->val;

            dfs(root->right, k);
        }
    }
public:
    int kthSmallest(TreeNode* root, int k) {
        dfs(root, k);
        return ans;
    }
};

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

    思路:
        递归构造二叉搜索树,每次选中间值作为根结点,左边比它小的值构造一棵左子树,右边比它大的值构造一棵右子树,每棵子树的根节点是其中间值。

class Solution {
    TreeNode* dfs(vector<int> &nums, int l, int r) {
        if (l > r) return nullptr;
        int mid = l + ((r - l) >> 1);
        TreeNode *root = new TreeNode(nums[mid]);
        root->left = dfs(nums, l, mid - 1);	/* 构造左子树 */
        root->right = dfs(nums, mid + 1, r); /* 构造右子树 */
        return root; /* 返回子树的根节点 */
    }
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        return dfs(nums, l, r);
    }
};

4. 1382. 将二叉搜索树变平衡

    思路:
        平衡二叉树,即每个结点的左右子树的高度相差不超过1。
        (1)中序遍历按升序将二叉搜索树中的每个结点的值放入数组ret
        (2)按照第三题的思路,递归构造二叉搜索树,由于构造方法是找一个根节点,构造左右子树,所以构造出来的二叉搜索树一定是平衡的。

class Solution {
    vector<int> ret;

    void inorder(TreeNode *root) { /* 中序遍历,并保存遍历结果在 ret 中 */
        if (root) {
            inorder(root->left);
            ret.push_back(root->val);
            inorder(root->right);   
        }
    }

    TreeNode *dfs(int l, int r) {   /* 递归构造平衡二叉搜索树 */
        if (l > r) return nullptr;
        int mid = l + ((r - l) >> 1);
        TreeNode *root = new TreeNode(ret[mid]);
        root->left = dfs(l, mid - 1);
        root->right = dfs(mid + 1, r);
        return root;
    }
public:
    TreeNode* balanceBST(TreeNode* root) {
        ret.clear();
        inorder(root);  /* 利用中序遍历二叉搜索树,得到一个有序数组 */

        int l = 0, r = ret.size() - 1;
        return dfs(l, r);
    }
};

posted @ 2022-05-20 06:35  番茄元  阅读(32)  评论(0)    收藏  举报