LeetCode BST专题

LeetCode连接:BST

0 BST核心内容

0.二叉树的核心内容 +
1.基本性质:左子树都小于根,右子树都大于根。
2.重要性质:BST的中序遍历序列递增有序

1 二叉搜索树的定义

典例 验证BST树

题目:给出一个二叉树,验证其是否是BST。
思路:
方法一:利用BST的“重要性质”:BST的中序遍历序列递增有序。中序遍历此二叉树,判断是否递增有序。

vector<int> vec;
    void inOrder(TreeNode* root){
        if(root == nullptr )    return;

        inOrder(root->left);
        vec.push_back(root->val);
        inOrder(root->right);
    }
 bool isValidBST(TreeNode* root) {
             inOrder(root);
             for(int i = 0;i < vec.size()-1;++i)   if(vec[i] >= vec[i+1]) return false;
             return true;
    }

方法二:利用BST的“基本性质”:左子树都比根小,右子树都比根大。
误区:最开始一直想的是求出左右子树的最大最小值,先求出子树的最值,然后和根比较,是 “自底向上” 的后序思想。但实现过程中涉及到大量的重复计算,而且终点设计比较麻烦。
既然“自底向上”不行,那就换用 “自顶向下”的先序思想,将合法的区间传下去,这样只用在子树判断是否合法就行了。

// 方法一: 从根节点传一个合法区间下去,判断树是否在合法区间内
    bool isOk(TreeNode* root,long long low,long long high){
        if(root == nullptr) return true;

        // 先判断根是否满足
        if(root->val <= low || root->val >= high)  return false;

        if(isOk(root->left,low,root->val) == false) return false;

        return  isOk(root->right,root->val,high);

    }
bool isValidBST(TreeNode* root) {
            return isOk(root,LONG_MIN,LONG_MAX);
    }

2 BST的基本操作

2.1 BST的查找

2.2 BST的插入

在查找为 null 时插入。

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

    }

    TreeNode* insertIntoBST(TreeNode* root, int val) {
        insert(root,val);
        return root;
    }

2.3 BST的删除

典例 BST的删除

老版思路:寻找前趋后继,然后用其代替。
高效思路:递归函数返回删除节点后的根节点。

root->val > key: 在左子树中删除,更新左指针;
root->val < key: 在右子树中删除,更新右指针;
root->val = = key :
  左子树为空:直接用右子树代替;
 右子树为空:直接用左子树代替;
 左右都不空:寻找右子树的最小节点 min,将左子树挂到 min 上,然后用右子树替代

左右都为空的情况?实际上,已经包含在了左/右为空的情况里面,若为空,则用  右/左替代,实际上就是用 null 替代,即为删除。

自底向上的后序思想。

 // 返回删除了节点后的树根
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(root ==nullptr)  return nullptr;

        if( root->val > key)  {
            root->left = deleteNode(root->left,key);
        }else if(root->val < key) {
            root->right = deleteNode(root->right,key);
        }else {
            if(root->left == nullptr)   return root->right;
            if(root->right == nullptr) return root->left;
            TreeNode* cur = root->right;
            while(cur->left != nullptr)    cur = cur->left;
            cur->left = root->left;
            root = root->right;
        }
        return root;

    }

3 总结

典例 将有序数组转换成AVL

贪心:取序列的中点作为根,划分左右区间,递归划分下去构造子树。

 TreeNode* create(vector<int>& nums,int start,int end){
        if(start > end) return nullptr;

        int mid = start + (end-start)/2;
        TreeNode* root = new TreeNode(nums[mid]);
        root->left = create(nums,start,mid-1);
        root->right = create(nums,mid+1,end);
        return root;
    }

    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return create(nums,0,nums.size()-1);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值