修剪二叉搜索树
题目链接:力扣
再一开始拿到题目的时候,参考了昨天删除二叉树节点的方法,写出如下错误代码:
错误点:例如当前点的值小于low,因为要删除节点的右子树不一定完全在指定区间内,所以不能直接 return root->right; 而是要继续向右遍历,在我们的规则下,继续修剪我们要删除节点的右子树。
TreeNode* trimBST(TreeNode* root, int low, int high) {
if(!root)
return nullptr;
if(root->val < low || root->val > high)
{
if(root->val < low && !root->right) //小于最小边界,右子不存在,就返回nullptr
return nullptr;
else if(root->val < low && root->right) //小于最小边界,右子存在就取右子,左子存不存在都舍弃
return root->right;
else if(root->val > high && !root->left)//大于最大边界,左子不存在,就返回nullptr
return nullptr;
else if(root->val > high && root->left ) //大于最大边界,左子存在就取左子,右子存不存在都舍弃
return root->left;
}
root->left = trimBST(root->left,low,high);
root->right = trimBST(root->right,low,high);
return root;
}
关键点:
递归函数返回值:
当前点的值小于low:
返回要删节点的右子树在指定区间修剪完之后的新的根节点
当前点的值大于high:
返回要删节点的左子树在指定区间修剪完之后的新的根节点
TreeNode* trimBST(TreeNode* root, int low, int high) {
if(!root)
return nullptr;
if(root->val < low) return trimBST(root->right,low,high);
if(root->val > high) return trimBST(root->left,low,high);
root->left = trimBST(root->left,low,high);
root->right = trimBST(root->right,low,high);
return root;
}
将有序数组转换为二叉搜索树
题目链接:力扣
这题采用二分法
为了防止越界:尽量将(left+right)/2 改为 left+((right-left)/2);
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return traversal(nums,0,nums.size()-1);
}
TreeNode* traversal(vector<int>& nums, int left, int right)
{
if(left > right)
return nullptr;
int midvalu = nums[(left + right)/2];
TreeNode* midNode = new TreeNode(midvalu);
midNode->left = traversal(nums,left,(left+right)/2-1);
midNode->right = traversal(nums,(left+right)/2+1, right);
return midNode;
}
};
把二叉搜索树转换为累加树
题目链接:力扣
知识点:双指针,节点pre用于保存前一个节点的值。这题和二叉树最小绝对值差 以及 二叉树的众数 使用的方法是一样的。
class Solution {
public:
TreeNode* convertBST(TreeNode* root) {
TreeNode* cur = root;
traversal(cur);
return root;
}
TreeNode* pre = nullptr;
void traversal(TreeNode* cur)
{
if(!cur) return;
traversal(cur->right);
if(pre !=nullptr)
cur->val = cur->val + pre->val;
pre = cur;
traversal(cur->left);
}
};