LC 669. 修剪二叉搜索树
题目链接:LC 669. 修剪二叉搜索树
思路:删除多个节点,上一章节的删除一个节点是找到要删除元素后,将元素的孩子返回,再用上一层的节点接住返回的孩子。本题是将不在规定范围内的节点,对于某些节点有两个孩子,但是要删除该节点,又要改变树的结构(像上一题)。但是该题中,若节点不在规定范围中,那么该节点的左子树也不在规定区间(节点小于规定区间)或者右子树不在规定区间(节点大于规定区间)。所以不用像上一题,考虑节点的结构变化。
代码:
/**
* 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 == nullptr)return nullptr;
//递归规则
//当不在规定区间时
if(root->val<low){//比规定区间小,就去根节点的右子树(比根节点的值大)
TreeNode* right = trimBST(root->right, low, high);
return right;
}
else if(root->val>high){//比规定区间大,就去根节点的左子树(比根节点值小)
TreeNode* left = trimBST(root->left, low, high);//看左子树是否符合
return left;
}
//当在规定区间内时
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
return root;
}
};
LC 108.将有序数组转换为二叉搜索树
题目链接:LC 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 nullptr;
//递归逻辑
//当只剩一个节点就构造一个节点直接返回
TreeNode* cur = new TreeNode(0);
int size = nums.size();
if(size==1){
cur->val = nums[0];
return cur;
}
//当剩下多个,就寻找中心节点
int midId = size/2;
cur->val = nums[midId];
vector<int> left(nums.begin(), nums.begin()+midId);
vector<int> right(nums.begin()+midId+1, nums.end());
cur->left = sortedArrayToBST(left);
cur->right = sortedArrayToBST(right);
return cur;
}
};
LC 538.把二叉搜索树转换为累加树
题目链接:LC 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:
//遍历顺序为右中左,保存第一个值,之后每次用前面的值更新遍历的值,再保存
int per = 0;//保存前面一个值,初始化为0是为了让第一个节点加0为本身,(不能设为-1,万一中间加的值等于-1就报错)
void traversal(TreeNode* cur){
//终止条件
if(cur==nullptr)return;
//否则进入递归逻辑
//先进入右子树
traversal(cur->right);
//当到了最右叶子节点
//若不是第一个节点
cur->val = cur->val+per;
per = cur->val;
traversal(cur->left);
}
TreeNode* convertBST(TreeNode* root) {
per = 0;
traversal(root);
return root;
}
};