首先要审题 题目说了是二叉搜索树 因此有了这个条件可以在判断时省略许多判断 条件
思路其实是比较绕的。最终的代码倒是很简洁。
我用的是后续遍历 由下往上进行反回结点 因此处理逻辑在左右递归的后面
- 确定终止条件
修剪的操作并不是在终止条件上进行的,所以就是遇到空节点返回就可以了。
- 确定单层递归的逻辑
如果root(当前节点)的元素小于low的数值,那么应该返回右结点。
如果root(当前节点)的元素大于high的数值,那么应该返回左结点。
如果满足条件就返回root 本身
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == nullptr) return nullptr;
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
if (root->val < low) {
return root->right;
}
if (root->val > high) {
return root->left;
}
return root;
}
};
这道题想了一会才做出来了,因此二刷有必要回顾一下 主要思想就是不断对数组分为一半然后放入递归构建结点 并且 只要划半构建出来的二叉树一定是平衡的
本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间。
完整代码如下:
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
if (nums.size() == 0) return nullptr;
if (nums.size() == 1) return new TreeNode(nums[0]);
TreeNode* mid = new TreeNode(nums[nums.size() / 2]);
vector<int> leftvec(nums.begin(), nums.begin() + nums.size() / 2);
vector<int> rightvec(nums.begin() + nums.size() / 2 + 1, nums.end());
mid->left = sortedArrayToBST(leftvec);
mid->right = sortedArrayToBST(rightvec);
return mid;
}
};
代码随想录里的提供的代码是不新构建向量的方法
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;
}
};
这道题目也是项链许久并且写的过程中也是一路坎坷 最终还是写出来了
值得注意的 是这个题目也是二叉搜索树以要找比自己节点的值都要从右子树开始找因此这道题目的遍历顺序是右中左 然后使用双指针的方法累加前一个节点的值就能够实现了
class Solution {
public:
TreeNode* pre = nullptr;
TreeNode* convertBST(TreeNode* root) {
if (root == nullptr) return nullptr;
convertBST(root->right);
if (pre != nullptr) {
root->val += pre->val;
}
pre = root;
convertBST(root->left);
return root;
}
};