第一题:
AC了啊啊啊啊啊啊,果然画图模拟最能让思路清晰了!:
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == nullptr) return nullptr;
if (root->val > high) { //右子树和根节点全部剪掉,只遍历左子树;
root = trimBST(root->left, low, high);
}
else if (root->val < low) { //左子树和根节点全部剪掉,只遍历右子树;
root = trimBST(root->right, low, high);
}
else if (root->val == low) { //左子树全部剪掉,继续排查右子树;
root->left = nullptr;
root->right = trimBST(root->right, low, high);
}
else if (root->val == high) { //右子树全部剪掉,继续排查左子树;
root->right = nullptr;
root->left = trimBST(root->left, low, high);
}
else { //根节点保留,排查左子树和右子树
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
}
return root;
}
};
有一点冗余,但是思路比较清晰,可以精简成以下:
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == nullptr) return nullptr;
if (root->val > high) {
root = trimBST(root->left, low, high);
}
else if (root->val < low) {
root = trimBST(root->right, low, high);
}
else {
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
}
return root;
}
};
如此和代码随想录的大差不差。
学习记录:
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == nullptr ) return nullptr;
if (root->val < low) {
TreeNode* right = trimBST(root->right, low, high); // 寻找符合区间[low, high]的节点
return right;
}
if (root->val > high) {
TreeNode* left = trimBST(root->left, low, high); // 寻找符合区间[low, high]的节点
return left;
}
root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子
root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子
return root;
}
};
第二题:
已AC:
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
if (nums.size() == 0) return nullptr;
int size = nums.size();
TreeNode* root = new TreeNode(nums[size/2]);
vector<int> leftnums(nums.begin(), nums.begin() + (size/2));
vector<int> rightnums(nums.begin() + (size/2) + 1, nums.end());
root->left = sortedArrayToBST(leftnums);
root->right = sortedArrayToBST(rightnums);
return root;
}
};
学习记录:
代码随想录代码,不创建新数组,而是用left和right指针,因为懒得重开一个函数我就没这么写,但是为了速度和内存,还是这样写吧...
class Solution {
public:
TreeNode* createBST(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 = createBST(nums, left, mid - 1);
root->right = createBST(nums, mid + 1, right);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return createBST(nums, 0, nums.size()-1);
}
};
第三题:
已AC。因为是二叉搜索树,所以思路是用一个全局变量sum存储右子树的总和(动态改变),每个节点的值都等于自己加上sum,然后再修改sum,先遍历右子树找到最右的节点,然后一层一层改值返回,如果当前节点有左子节点,那么也遍历左子树修改:
class Solution {
public:
int sum = 0;
TreeNode* convertBST(TreeNode* root) {
if (root == nullptr) return root;
root->right = convertBST(root->right);
sum = root->val + sum;
root->val = sum;
if (root->left) {
root->left = convertBST(root->left);
}
return root;
}
};
学习记录:
代码随想录中说道是反中序遍历 ,事实上我的思路也是这样写的,先右、中,再左:
class Solution {
private:
int pre = 0; // 记录前一个节点的数值
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;
}
};