🎋 1382.将二叉搜索树变平衡
给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。如果有多种构造方法,请你返回任意一种。
如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平衡的
思路
基本思想
将二叉搜索树变平衡,可以将问题拆解,现将其转化为中序遍历的序列存储到vector中,然后将vector中的元素转化为平衡二叉树,最终实现将二叉搜索树变平衡的说法。
一旦将问题分解,唯一的难点就在将中序遍历序列转化为平衡二叉树,可以参考
108题
,需要计算二叉树中节点的位置,使用类似于二叉搜索的思想,每次丢弃一半的元素,找到目标的元素,直接申请新节点,在创建平衡二叉树的过程中有几点需要注意:
- 得到中序遍历序列时,必须传递引用,否则中序遍历的结果无法存储到vector容器中
- 由容器中的元素构建平衡二叉树时,传递的范围必须是有效元素的范围,也就是
(0,res.size()-1)
,而不是(0,res.size())
,后者会造成空指针访问的情况,因为当pos=res.size()
时,也会尝试访问容器中的元素
执行流程
- 得到中序遍历序列
- 根据中序遍历序列得到平衡二叉树
代码
根据以上分析,得出以下代码:
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;
}
};
|
总结
将问题分解,变成两个简单的问题,需要注意参数传递时传递引用,传递元素范围时需要传递有效元素的范围