今天的题目还行,不算难,第一道题看视频后做出来的,后两道题都是自己做的,没看视频直接AC,开心😊
669. 修剪二叉搜索树
这道题目依旧是用递归来做,这道题目最关键的一点在于:当节点的值小于最小值时,就无需遍历其左子树,因为左子树的值一定都小于最小值,仅需遍历其右子树;当节点的值大于最大值时,就无需遍历其右子树,因为右子树的值一定都大于最大值,仅需遍历其左子树。这道题目和之前的删除节点很像,但是代码逻辑没有那么复杂,不需要分那么多种情况讨论。
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
//确定终止条件
if(root == NULL) return NULL;
if(root -> val < low){ //无需遍历左孩子,因为左子树不为空也不可能满足
TreeNode* right = trimBST(root -> right, low, high);
return right;
}
if(root -> val > high){ //无需遍历右孩子,因为右子树不为空也不可能满足
TreeNode* left = trimBST(root -> left, low, high);
return left;
}
root -> left = trimBST(root -> left, low, high);
root -> right = trimBST(root -> right, low, high);
return root;
}
};
108.将有序数组转换为二叉搜索树
这个题目用递归来做,因为给出的数组是已经升序排列过了,所以取数组中间的值作为根节点,该值左边的作为左子树,该值右边的作为右子树,这样就能保证构造出来的一定是平衡二叉树(因为剩下的左右两侧的元素个数相近),不断地用中位数分割数组可以保证构造出来的一定是二叉搜索树。
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
//确定终止条件
if(nums.size() == 0) return NULL;
//传入数组不为空
int SIZE = nums.size();
TreeNode* root = new TreeNode(nums[SIZE / 2]);
vector<int> sub_left(nums.begin(), nums.begin() + SIZE / 2);
vector<int> sub_right(nums.begin() + SIZE / 2 + 1, nums.end());
root -> left = sortedArrayToBST(sub_left);
root -> right = sortedArrayToBST(sub_right);
return root;
}
};
538.把二叉搜索树转换为累加树
这道题目用双指针来做,这道题采用递归,中序遍历,但是这里的中序遍历与我们常规的“左 - 中 - 右”不同,本题我们采用“右 - 中 - 左”来遍历,为什么?因为从题目给出的案例来看,按照这样的遍历顺序去遍历,当前节点的新的值总是等于当前节点原来的值 + 前一个节点的新的值,这样遍历的话不需要额外的空间开销和时间开销,如果采用常规的“左 - 中 - 右”的话,还需要先遍历一遍二叉树计算出所有节点之和,再将总和减去当前节点的值作为当前节点的新值,实现起来也会更加麻烦。
class Solution {
public:
TreeNode* pre = NULL;
TreeNode* convertBST(TreeNode* root) {
//确定终止条件
if(root == NULL) return NULL;
//右
root -> right = convertBST(root -> right);
//中
if(pre != NULL)
root -> val = root -> val + pre -> val;
pre = root;
//左
root -> left = convertBST(root -> left);
return root;
}
};
二叉树完结撒花!!!