给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
示例 1:
输入:
1
/ \
0 2
L = 1
R = 2
输出:
1
\
2
示例 2:
输入:
3
/ \
0 4
\
2
/
1
L = 1
R = 3
输出:
3
/
2
/
1
思路分析: 这道题与 LeetCode 删除二叉搜索树中的节点 非常类似,蛋试相比之下简单很多。
首先,我们知道二叉搜索树的定义是:左子树的节点元素值 < root的值 < 右子树的节点元素值,并且左子树、右子树同样满足这个条件(递归定义)。
算法描述:
如果root的值 < L,说明,root和root->left都需要删除(因为左子树的节点元素值 < root的值 < L)
如果R < root的值,说明,root和root->right都需要删除(因为R < root的值 < 右子树的节点元素值)
否则,我们递归修剪root->left、root->right,然后放到root的左子树、右子树
递归算法一般比较简洁,蛋试理解可能比较困难。我们不要深究每一步是怎么实现的,我们只要知道如果root的值不需要删减,就递归删减root->left,root->right,否则会越想越复杂。
我发现居然不能回收空间,一回收就报错。。。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int L, int R) {
if (root == NULL) {
return NULL;
}
if (root->val < L) {
//左子树的节点元素值 < root的值 < L,只保留右子树
TreeNode *newRoot = root->right;
//root->right = NULL;
//myDelTree(root);
return trimBST(newRoot, L, R);
}
else if (root->val > R) {
//R < root的值 < 右子树的节点元素值,值保留左子树
TreeNode* newRoot = root->left;
//root->left = NULL;
//myDelTree(root);
return trimBST(newRoot, L, R);
}
else {
//否则,递归修剪左子树、右子树,保留根节点
root->left = trimBST(root->left, L, R);
root->right = trimBST(root->right, L, R);
return root;
}
}
//删除以root为根的树
void myDelTree(TreeNode* root) {
if (root == NULL) {
return;
}
myDelTree(root->left);
myDelTree(root->right);
delete root;
}
};