刷题的第十九天,希望自己能够不断坚持下去,迎来蜕变。
刷题语言:C++
Day19 任务
● 669. 修剪二叉搜索树
● 108.将有序数组转换为二叉搜索树
● 538.把二叉搜索树转换为累加树
TreeNode* trimBST(TreeNode* root, int low, int high)
(2)确定终止条件
if (root == NULL) return NULL;
(3)确定单层递归的逻辑
如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点
if (root->val < low) {
TreeNode* right = trimBST(root->right, low, high);// 寻找符合区间[low, high]的节点
return right;
}
如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。
if (root->val > high) {
TreeNode* left = trimBST(root->left, low, high);// 寻找符合区间[low, high]的节点
return left;
}
将下一层处理完左子树的结果赋给root->left,处理完右子树的结果赋给root->right。最后返回root节点
root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子
root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子
return root;
C++:
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;
}
};
本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间
如果要分割的数组长度为偶数的时候,中间元素为两个,是取左边元素 就是树1,取右边元素就是树2。
递归法
(1)确定递归函数返回值及其参数
参数:数组、左下标left、右下标right
返回值:TreeNode*
// 左闭右闭区间[left, right]
TreeNode* traversal(vector<int>& nums, int left, int right)
定义的是左闭右闭区间,在不断分割的过程中,也会坚持左闭右闭的区间(循环不变量)
(2)确定递归终止条件
if (left > right) return NULL;
(3)确定单层递归的逻辑
- 取数组中间元素的位置
- 以中间位置的元素构造节点
- 划分区间,root的左孩子接住下一层左区间的构造节点,右孩子接住下一层右区间构造的节点。
- 最后返回root节点
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;
C++:
class Solution {
public:
TreeNode* traversal(vector<int>& nums, int left, int right) {
if (left > right) return NULL;
int mid = (left + right) / 2;
TreeNode* root = new TreeNode(nums[mid]);
root->left = traversal(nums, left, mid - 1);
root->right = traversal(nums, mid + 1, right);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return traversal(nums, 0, nums.size() - 1);
}
};
二叉搜索树有序,中序遍历(左中右)得到有序数组,将有序数组向前累加:右中左
反中序遍历这个二叉树,然后顺序累加
递归法
需要一个pre记录当前遍历节点cur的前一个节点的值,方便做累加。
(1)递归函数参数以及返回值
参数:当前节点
返回值:void
int pre = 0;// 记录前一个节点的数值
void traversal(TreeNode* cur)
(2)确定终止条件:遇空就终止
if (cur == NULL) return;
(3)确定单层递归的逻辑
右中左来遍历二叉树
traversal(cur->right);// 右
cur->val += pre; // 中
pre = cur->val;
traversal(cur->left); // 左
C++:
class Solution {
public:
int pre = 0;// 记录前一个节点的数值
void traversal(TreeNode* cur) {// 右中左遍历
if (cur == NULL) return;
traversal(cur->right);
cur->val += pre;
pre = cur->val;
traversal(cur->left);
}
TreeNode* convertBST(TreeNode* root) {
traversal(root);
return root;
}
};
鼓励坚持二十天的自己