669. 修剪二叉搜索树
给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
这里遇到了一个技巧,那就是,当我们找到需要修剪的地方时,比如说找到了小于某个点的边界,这时我们仍然需要对它的右子树进行修剪,递归算法如下所示:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* trim(TreeNode* root,int low,int high){
if(root==NULL)return root;
if(root->val<low)
{
auto right=trim(root->right,low,high);
return right;
}
if(root->val>high)
{
auto left=trim(root->left,low,high);
return left;
}
root->left=trim(root->left,low,high);
root->right=trim(root->right,low,high);
return root;
}
TreeNode* trimBST(TreeNode* root, int low, int high) {
return trim(root,low,high);
}
};
108.将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
easy,会用中序和前序构造二叉树之后,这题很简单,每次将数组二分就行,用中间的节点当成根节点:
class Solution {
public:
TreeNode* sorted(vector<int>& nums){
if(nums.size()==0)return NULL;
if(nums.size()==1)return new TreeNode(nums[0]);
vector<int> left;
vector<int> right;
int mid=nums.size()/2;
auto root=new TreeNode(nums[mid]);
left=vector<int>(nums.begin(),nums.begin()+mid);
right=vector<int>(nums.begin()+mid+1,nums.end());
/*for(int i=0;i<mid;i++)
{
left.push_back(nums[i]);
}
for(int i=mid+1;i<nums.size();i++)
{
right.push_back(nums[i]);
}
*/
root->left=sorted(left);
root->right=sorted(right);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return sorted(nums);
}
};
538.把二叉搜索树转换为累加树
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。 节点的右子树仅包含键 大于 节点键的节点。 左右子树也必须是二叉搜索树。
示例 1:
简单,右中左遍历,然后双指针就行:
class Solution {
public:
TreeNode* prenode=NULL;
void traversal(TreeNode* root){
if(root==NULL)return;
traversal(root->right);
if(prenode!=NULL)
root->val+=prenode->val;
prenode=root;
traversal(root->left);
return;
}
TreeNode* convertBST(TreeNode* root) {
traversal(root);
return root;
}
};
当然,迭代法也是类似的,中序遍历的左右反过来就行:
class Solution {
public:
TreeNode* convertBST(TreeNode* root) {
stack<TreeNode*> st;
auto cur=root;
TreeNode* pre=NULL;
while(cur!=NULL||!st.empty()){
if(cur!=NULL)
{
st.push(cur);
cur=cur->right;
}
else
{ auto temp=st.top();
st.pop();
if(pre!=NULL)
temp->val+=pre->val;
pre=temp;
cur=temp->left;
}
}
return root;
}
};