669. 修剪二叉搜索树
题目链接:修剪二叉搜索树
题目描述:给你二叉搜索树的根节点
root
,同时给定最小边界low
和最大边界high
。通过修剪二叉搜索树,使得所有节点的值在[low, high]
中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
解题思想:
理解了最关键部分了我们再递归三部曲:
-
确定递归函数的参数以及返回值
因为是要遍历整棵树,做修改,其实不需要返回值也可以,我们也可以完成修剪(其实就是从二叉树中移除节点)的操作。但是有返回值,更方便,可以通过递归函数的返回值来移除节点。 -
确定终止条件
修剪的操作并不是在终止条件上进行的,所以就是遇到空节点返回就可以了。 -
确定单层递归的逻辑
如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。
接下来要将下一层处理完左子树的结果赋给root->left,处理完右子树的结果赋给root->right。
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == NULL)
return NULL;
if (root->val < low) {
TreeNode* left = trimBST(root->right, low, high);
return left;
}
if (root->val > high) {
TreeNode* right = trimBST(root->left, low, high);
return right;
}
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
return root;
}
};
108.将有序数组转换为二叉搜索树
题目链接:二叉搜索树中的插入操作
题目描述:给你一个整数数组
nums
,其中元素已经按升序排列,请你将其转换为一棵平衡二叉搜索树。
解题思想:
题目中说要转换为一棵高度平衡二叉搜索树。为什么强调要平衡呢?因为只要给我们一个有序数组,如果强调平衡,都可以以线性结构来构造二叉搜索树。例如 有序数组[-10,-3,0,5,9] 就可以构造成这样的二叉搜索树,如图。
其实数组构造二叉树,构成平衡树是自然而然的事情,因为大家默认都是从数组中间位置取值作为节点元素,一般不会随机取。所以想构成不平衡的二叉树是自找麻烦。
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (root == NULL) {
TreeNode* node = new TreeNode(val);
return node;
}
if (val < root->val) {
root->left = insertIntoBST(root->left, val);
}
if (val > root->val) {
root->right = insertIntoBST(root->right, val);
}
return root;
}
};
538.把二叉搜索树转换为累加树
题目链接:把二叉搜索树转换为累加树
题目描述:给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点
node
的新值等于原树中大于或等于node.val
的值之和。提醒一下,二叉搜索树满足下列约束条件:
- 节点的左子树仅包含键 小于 节点键的节点。
- 节点的右子树仅包含键 大于 节点键的节点。
- 左右子树也必须是二叉搜索树。
**注意:**本题和 1038: https://leetcode-cn.com/problems/binary-search-tree-to-greater-sum-tree/ 相同
解题思路:
二叉搜索树中序遍历为递增有序数列,从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了。
递归法:
class Solution {
public:
TreeNode* convertBST(TreeNode* root) {
traversal(root);
return root;
}
private:
TreeNode* pre = NULL;
void traversal(TreeNode* cur) {
if (cur == NULL)
return;
traversal(cur->right);
if (pre != NULL) {
cur->val = cur->val + pre->val;
}
pre = cur;
traversal(cur->left);
}
};
迭代法:
迭代法其实就是中序模板题了
class Solution {
public:
TreeNode* convertBST(TreeNode* root) {
stack<TreeNode*> st;
TreeNode* pre = NULL;
TreeNode* cur = root;
while (cur != NULL || !st.empty()) {
if (cur != NULL) {
st.push(cur);
cur = cur->right;
} else {
cur = st.top();
st.pop();
if (pre != NULL) {
cur->val += pre->val;
}
pre = cur;
cur = cur->left;
}
}
return root;
}
};