669.修建二叉搜索树
思路:不能直接删除比区间小的或大的节点。例如比low小的根节点,虽然左子树都比根节点小可以全删,但是其右子树可能是存在区间内符合条件的值,所以需要在其根节点右子树继续遍历找到不符合条件的节点删除。比high大的思路和比low小的一样。
代码:
TreeNode* trimBST(TreeNode* root, int low, int high) {
//如果当前val不符区间,则在相应的左右子树继续修剪
if(root == nullptr) return nullptr;
if(root->val < low){//当前root以及左子树都比low小,但是右子树有可能有比low大的,遍历右子树,如果有比low还小的则删除
TreeNode* right = trimBST(root->right,low,high);
return right;
}
if(root->val > high){
TreeNode* left = trimBST(root->left,low,high);
return left;
}
//如果val值在区间内则下面遍历整颗树
root->left = trimBST(root->left,low,high);
root->right = trimBST(root->right,low,high);
return root;
}
108.将有序数组转换为二叉搜索树
思路:二叉搜索树需要平衡,可以去数组最中间的元素作为树的根节点,从此点分割为左右子数组(子树),再递归进行取数组中间数构造.因为该数组是单调递增的,所以左数组在左边,右数组在右边,不会破坏搜索树特性。
代码:
TreeNode* traversal(vector<int>& nums,int low,int high){
if(low > high) return nullptr;//此时数组元素为0
int middle = (low+high)/2;//找到数组中间切割点
TreeNode* root = new TreeNode(nums[middle]);
root->left = traversal(nums,low,middle-1);
root->right = traversal(nums,middle+1,high);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return traversal(nums,0,nums.size()-1);//区间为左闭右闭
}
538.把二叉搜索树转换为累加树
思路:题意是从最右下开始进行累加,并且是右中左进行累加,所以用右中左遍历顺序,利用双指针法,pre指向之前的节点累加值和cur值累加。
代码:
int pre = 0;//记录前一个节点的值
void traversal(TreeNode* cur){
if(cur == nullptr) return;
//右
traversal(cur->right);
//中
cur->val += pre;
pre = cur->val;
//左
traversal(cur->left);
}
TreeNode* convertBST(TreeNode* root) {
traversal(root);
return root;
}