刷题心得7-二叉搜索树

二叉搜索树的性质:

根节点左侧的节点值都小于当前节点的值,根节点右侧节点值都大于当前节点的值。

所以二叉搜索树的中序遍历结果就是排序好的数组

image-20240910114025939

所以大多二叉搜索树的题都可以用中序遍历来做。

题目1:

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

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。

class Solution {
public:
    TreeNode* sortedArray(vector<int>& nums,int l,int r){
        //建树,每次都拿中点位置当作二叉搜索树的根
        if(l>r) return nullptr;
        //以当前的中点当作当前的根
        int mid = (l+r)/2;
        TreeNode* root = new TreeNode(nums[mid]);//这是当前的根
        //找他的左右根
        TreeNode *ll = sortedArray(nums,l,mid-1);
        TreeNode *rr = sortedArray(nums,mid+1,r);
        root->left = ll;
        root->right = rr; 
        return root;
    }

    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return sortedArray(nums,0,nums.size()-1);
    }
};

题目2:

98. 验证二叉搜索树 - 力扣(LeetCode)

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左

    子树

    只包含

    小于

    当前节点的数。

  • 节点的右子树只包含 大于 当前节点的数。

  • 所有左子树和右子树自身必须也是二叉搜索树。

这个也可以用中序遍历来判断。

以下是题解做法,每次都传当前可以满足的最大和最小值,返回的bool值,判断是否满足条件(我之前使用的找每个节点左侧的最大值和右侧的最小值,然后再遍历一遍看是否满足条件,以下,可以过,但比较难写并且时间复杂度高)

class Solution {
public:
    bool helper(TreeNode* root, long long lower, long long upper){
        //判断当前root值是否满足lower到upper的区间
        if(root->val>=upper||root->val<=lower){
            return false;
        }
        if(root->left){
            bool v = helper(root->left,lower,root->val);//对于左边要满足小于root.val
            if(!v) return false;
        }
        if(root->right){
            bool v = helper(root->right,root->val,upper);
            if(!v) return false;
        }
        return true;
    }
    bool isValidBST(TreeNode* root) {
        return helper(root, LONG_MIN, LONG_MAX);
    }
};

题目3:

230. 二叉搜索树中第 K 小的元素 - 力扣(LeetCode)

这个就直接使用中序遍历就可以得到第k个值就是答案

lass Solution {
public:
    int now;
    int kthSmallest(TreeNode* root, int k) { //第k小的元素,找到原数组,就可以得到第k个值了
        //变量方式是左根右的方式,按照这个顺序找
        int ans=-1;
        if(root->left){
            int v = kthSmallest(root->left,k);
            if(v!=-1){
                return v;
            }
        }
        now++;
        if(now==k){
            return root->val;
        }
        if(root->right){
            int v = kthSmallest(root->right,k);
            if(v!=-1){
                return v;
            }
        }
        return ans;
    }
};
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值