一、修剪二叉树
链接:力扣
描述:给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。
所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
思路:按照中左右的处理逻辑,是将其返回到上一层递归的中结点的左右子树。注意如果是遍历到了某一个结点,比low小,则不能直接返回Null,因为它的右子树里可能有在low,high区间里的结点,也不能直接返回该结点的右子树,因为右子树里也有可能需要进行删除的结点。对于比high大的情况,也同理可得。
代码如下:
#include <iostream>
using namespace std;
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* trimBST(TreeNode* root, int low, int high)
{
if (!root)
{
return NULL;//将返回上一层
}
if (root->val < low)
{
//说明该结点应该删除,但是该结点的右子树可能有在这个区间的数
//需要向右子树进行搜索
return trimBST(root->right, low, high);
}
if (root->val > high)
{
//说明该结点应该删除,但是该结点的左子树可能有在这个区间的数
//需要向左子树进行搜索
return trimBST(root->left, low, high);
}
//用返回的新的结点连接到跟结点的左子树、右子树身上
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
return root;
}
};
运行如下:
二、 将有序数组转换为二叉搜索树
链接:力扣
描述:给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树
思路如下:找到分割点即可,本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间,这个数组本来就是有序的,只要每次都取中间值即可。注意当数组的元素个数是偶数的时候,取中间两个值任意一个都行,对应于两颗不同的二叉搜索树。
代码如下:
#include <iostream>
#include <vector>
using namespace std;
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* sortedArrayToBST(vector<int>& nums)
{
int split_point = nums.size() >> 2;
if (nums.size() == 0)
{
//数组为空
return NULL;
}
TreeNode* root = new TreeNode(nums[split_point]);
vector<int>leftnums(nums.begin(), nums.begin() + split_point);
vector<int>rightnums(nums.begin() + split_point+1, nums.end());
root->left = sortedArrayToBST(leftnums);
root->right = sortedArrayToBST(rightnums);
return root;
}
};
运行如下:
三、 把二叉树转换为累加树
链接:力扣
描述:
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。
节点的右子树仅包含键 大于 节点键的节点。
左右子树也必须是二叉搜索树。
思路如下:按照右中左的顺序进行遍历,用一个全局变量来记录遍历到每一个节点需要加的值。
代码如下:
#include <iostream>
using namespace std;
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:
int pre = 0;//用于存之前遍历的结点的值
//按右中左的顺序进行遍历,遍历的结点的值需要加上这个pre
//先找到最右边的那个值,即最大
void traversal(TreeNode* cur)
{
if (!cur)
{
return;
}
traversal(cur->right);
cur->val += pre;
pre = cur->val;//更新pre的值用于下一个结点
traversal(cur->left);
}
TreeNode* convertBST(TreeNode* root)
{
traversal(root);
return root;
}
};
运行如下: