大家好啊,不知道大家国庆假期过得如何?
算法训练营休假5天期间大家有没有刷题?
有的话继续坚持,没有的话就当放松啦~
今天打卡二叉树的最后章节,同时不要忘记复习前面的章节,包括数组、字符串、链表、哈希表等内容!坚持就是胜利!
目录
1.修剪二叉搜索树
2.将有序数组转换为二叉搜索树
3.
题目1、669.修剪二叉搜索树
给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
思路:
有一个误区,可能我们会认为只需要通过前序遍历确定根节点,然后删除掉比左(右)val值小(大)的节点然后返回root就可以了,但是这样往往会把左右孩子的在区间内的左右孩子也同时删除,这样的做法并不符合题意。我们可以通过递归的方法,在traversal()函数的返回值中递归使用traversal()函数,达成删除不符合的节点的同时保留符合的节点。
代码实现:
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == nullptr) {
return nullptr;
}
if (root->val < low) {
// 如果当前节点的值小于 low,则修剪后的树是当前节点的右子树
return trimBST(root->right, low, high);
}
if (root->val > high) {
// 如果当前节点的值大于 high,则修剪后的树是当前节点的左子树
return trimBST(root->left, low, high);
}
// 如果当前节点的值在 [low, high] 范围内,则递归修剪左右子树
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
return root;
}
};
题目2、108.将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
关联题目
- 106.从中序与后序遍历序列构造二叉树(opens new window)
- 654.最大二叉树 (opens new window)
- 701.二叉搜索树中的插入操作(opens new window)
- 450.删除二叉搜索树中的节点
思路
首先我们要从数组的中间数字开始划分,划分成左右两个区间,然后在左右两个区间进行递归。
如何确定划分点呢?
为了确保不会发生越界,我们这样写 --> mid = left + (right - left) / 2
我们不需要再创建新的数组,在原来的数组的基础上改变下标,然后对左右区间进行遍历即可。
最后我们返回根节点。
代码实现
class Solution {
private:
TreeNode* traversal(vector<int>& nums, int left, int right) {
if (left > right) return nullptr;
int mid = left + ((right - left) / 2);
TreeNode* root = new TreeNode(nums[mid]);
root->left = traversal(nums, left, mid - 1);
root->right = traversal(nums, mid + 1, right);
return root;
}
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
TreeNode* root = traversal(nums, 0, nums.size() - 1);
return root;
}
};
题目3、538.把二叉搜索树转换为累加树
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。 节点的右子树仅包含键 大于 节点键的节点。 左右子树也必须是二叉搜索树。
示例 1:
- 输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
- 输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
示例 2:
- 输入:root = [0,null,1]
- 输出:[1,null,1]
示例 3:
- 输入:root = [1,0,2]
- 输出:[3,3,2]
示例 4:
- 输入:root = [3,2,4,1]
- 输出:[7,9,4,10]
思路
普大喜奔!二叉树章节已全部更完啦!| LeetCode:538.把二叉搜索树转换为累加树_哔哩哔哩_bilibili
代码实现
(思路相近,精简版运行效率更高)
版本1
class Solution {
private:
int pre;
void traversal(TreeNode* cur){
if (cur == NULL) return;
traversal(cur->right); // 右
cur->val += pre; // 中
pre = cur->val;
traversal(cur->left); // 左
}
public:
TreeNode* convertBST(TreeNode* root) {
pre = 0;
traversal(root);
return root;
}
};
版本2
class Solution {
public:
int sum = 0;
TreeNode* convertBST(TreeNode* root) {
if(root == nullptr)
{
return nullptr;
}
convertBST(root->right);
sum += root->val;
root->val = sum;
convertBST(root->left);
return root;
}
};
总结:二叉树章节告一段落,但是还要掌握迭代法的相关知识和巩固二叉树递归法的操作!