代码随想录算法训练营Day23|669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树
代码随想录算法训练营Day23|669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树
与删除节点类似,但不需要讨论左/右孩子节点是否为空:
原因在于删除节点时,如果左右孩子均非空,需要把左孩子挂在右孩子的最左叶子节点上。但如果二叉树一定范围内的节点删除,根节点值一定在左右孩子区间中,这样范围删除不会出现左右孩子均存在的情况。(因为删除范围是趋于无限的开区间!!)所以只需要考虑挂载一边的孩子节点分支即可。
/**
* Definition for a binary tree node.
* 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 == NULL) 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;
}
};
108. 将有序数组转换为二叉搜索树
如果根据数组构造一棵二叉树。本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间。
①开辟新数组空间
/**
* Definition for a binary tree node.
* 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) {
if (nums.size() == 0) return NULL;
int midIndex = nums.size() / 2;
TreeNode* root = new TreeNode(nums[midIndex]);
vector<int> leftVec(nums.begin(), nums.begin() + midIndex);
vector<int> rightVec(nums.begin() + midIndex + 1, nums.end());
root->left = sortedArrayToBST(leftVec);
root->right = sortedArrayToBST(rightVec);
return root;
}
};
②不开辟新数组空间
因为需要记录每次分割的边界,所以需要另外开辟一个递归函数。注意分割区间是「左闭右开」。
/**
* Definition for a binary tree node.
* 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) {
return buildBST(nums, 0, nums.size());
}
TreeNode* buildBST(vector<int>& nums, int left, int right) {
// 设置终止条件
if (left >= right) return NULL;
int midIndex = (left + right) / 2;
TreeNode* root = new TreeNode(nums[midIndex]);
root->left = buildBST(nums, left, midIndex);
root->right = buildBST(nums, midIndex + 1, right);
return root;
}
};
538. 把二叉搜索树转换为累加树
核心在于二叉搜索树的中序遍历为递增数组。
①先处理数组累加,再重新遍历来修改值
/**
* Definition for a binary tree node.
* 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* convertBST(TreeNode* root) {
vector<int> vec;
traversal(root, vec);
for (int i = vec.size() - 2; i >= 0; i--) {
vec[i] += vec[i + 1];
}
appendVal(root, vec);
return root;
}
void appendVal(TreeNode* root, vector<int>& vec) {
if (root == NULL) return;
appendVal(root->left, vec);
root->val = vec[0];
vec.erase(vec.begin());
appendVal(root->right, vec);
}
void traversal(TreeNode* root, vector<int>& vec) {
if (root == NULL) return;
traversal(root->left, vec);
vec.push_back(root->val);
traversal(root->right, vec);
}
};
②遍历的同时修改值
我们知道BST的中序遍历为递增数组,但题目要求总右节点开始累加,类比的思考:其实「右中左」的遍历顺序即可获得数组的倒序数组。此时我们统一了遍历顺序和处理数组的累加顺序,保持两者的一致性。因此我们可以在遍历的同时直接进行处理。
/**
* Definition for a binary tree node.
* 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* convertBST(TreeNode* root) {
traversal(root);
return root;
}
private:
int pre = 0;
void traversal(TreeNode* root) {
if (root == NULL) return;
// 右中左
traversal(root->right);
root->val += pre;
pre = root->val;
traversal(root->left);
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构