第一题: 669. 修剪二叉搜索树
这道题需要仔细地考虑清楚各种情况,不然很容易出错。用递归法解题更加容易理解,按照递归三部曲来进行。
第一步:确定函数的参数与返回值。参数有三个,分别是根节点root,下限low,上限high,返回值为新的根节点。
第二步:确定终止条件。当遍历的节点为nullptr时就返回nullptr。
第三步:单层递归逻辑。当root->val在[low, high]之内的时候,那么就继续遍历左子树和右子树,并分别用root->left和root->right来接收返回值;当root->val < low的时候,该节点以及该节点左子树上的值都不在区间内,而右子树上的值仍有可能在区间内,因此继续遍历右子树上的节点,并返回,上一层递归函数会接收到返回值;同理当root->val > high时,该节点以及右子树上的值都不在区间内,左子树上的值有可能在区间内,因此去遍历左子树上的节点,并返回结果。
具体代码如下:
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if(!root) return nullptr;
if(root->val > high) {
TreeNode* left = trimBST(root->left, low, high);
return left;
}
else if(root->val < low) {
TreeNode* right = trimBST(root->right, low, high);
return right;
}
else {
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
}
return root;
}
};
第二题: 108.将有序数组转换为二叉搜索树
这道题比较容易理解,可以想到解题的方法,要注意分清楚边界问题,只要处理好边界问题,这道题就能迎刃而解了。主要的思路就是,数组中间位置的元素作为root,再依次递归得到左子树与右子树。代码如下:
class Solution {
public:
TreeNode* traversal(vector<int>& nums, int begin, int end) {//左闭右闭区间[begin,end]
if(begin > end) return nullptr;
int base = begin + (end - begin) / 2;
TreeNode* root = new TreeNode(nums[base]);
root->left = traversal(nums, begin, base - 1);
root->right = traversal(nums, base + 1, end);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return traversal(nums, 0, nums.size() - 1);
}
};
第三题: 538.把二叉搜索树转换为累加树
这道题我的想法是按照右中左的顺序来遍历整颗二叉搜索树,这种方法能够很好的利用二叉搜素树的特性,即:每次遍历时得到的都是未遍历过的节点中的最大值,再设置一个全局变量sum来记录>=该节点的值之和。然后每次处理中间节点的时候,令node->val = sum即可。代码如下:
class Solution {
public:
int sum = 0;
TreeNode* convertBST(TreeNode* root) {
if(!root) return nullptr;
convertBST(root->right);
sum += root->val;
root->val = sum;
convertBST(root->left);
return root;
}
};
二叉树总结篇
二叉树问题几乎都可以通过递归法来解决,因此遇到二叉树相关的问题,可以先考虑使用递归法来解决问题。
以下几点要注意:
-
涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
-
求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
-
求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。
Day23打卡!!!