1382.将二叉搜索树变平衡

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

给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。如果有多种构造方法,请你返回任意一种。

如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平衡的

思路

基本思想

将二叉搜索树变平衡,可以将问题拆解,现将其转化为中序遍历的序列存储到vector中,然后将vector中的元素转化为平衡二叉树,最终实现将二叉搜索树变平衡的说法。

一旦将问题分解,唯一的难点就在将中序遍历序列转化为平衡二叉树,可以参考 108题 ,需要计算二叉树中节点的位置,使用类似于二叉搜索的思想,每次丢弃一半的元素,找到目标的元素,直接申请新节点,在创建平衡二叉树的过程中有几点需要注意:

  1. 得到中序遍历序列时,必须传递引用,否则中序遍历的结果无法存储到vector容器中
  2. 由容器中的元素构建平衡二叉树时,传递的范围必须是有效元素的范围,也就是(0,res.size()-1),而不是(0,res.size()),后者会造成空指针访问的情况,因为当pos=res.size()时,也会尝试访问容器中的元素

执行流程

  1. 得到中序遍历序列
  2. 根据中序遍历序列得到平衡二叉树

代码

根据以上分析,得出以下代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
    TreeNode* balanceBST(TreeNode* root) {
        //分为两步,第一步将二叉搜索树存放在有序数组中:使用中序遍历
        //第二步将有序数组转化成二叉搜索树
        vector<int> res;
        trans(root,res);
        //传递的元素范围必须是有效范围
        return create(res,0,res.size()-1);
    }
    //将二叉树转化成有序数组,传递的必须是引用,才能将结果保存到res中
    void trans(TreeNode *root,vector<int> &res){
        if(root==nullptr)
            return;
        trans(root->left,res);
        res.push_back(root->val);
        trans(root->right,res);
    }
    //将有序数组转化为平衡二叉树
    TreeNode* create(vector<int> res,int begin,int end){
        if(begin>end)
            return nullptr;
        int pos=(begin+end)/2;
        TreeNode *node=new TreeNode(res[pos]);
        node->left=create(res,begin,pos-1);
        node->right=create(res,pos+1,end);
        return node;
    }
};

总结

将问题分解,变成两个简单的问题,需要注意参数传递时传递引用,传递元素范围时需要传递有效元素的范围