(23/60)修剪二叉搜索树、将有序数组转化为二叉搜索树、把二叉搜索树转换为累加树
修剪二叉搜索树
leetcode:669. 修剪二叉搜索树
递归法
思路
和删除搜索树节点类似,递归向上返回子树。
-
碰到NULL节点,向上抛NULL;
-
如果值小于左边界,那么当前根节点和左子树都要剪掉,返回递归右子树的结果;
如果值大于右边界,那么当前根节点和右子树都要剪掉,返回递归左子树的结果;
-
root->left接收左子树递归结果;
root->right接收右子树递归结果;
-
返回root
复杂度分析
时间复杂度:O(logN)。
空间复杂度:O(logN)/O(N)。
注意点
略
代码实现
(未进行内存回收)
/**
* 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) 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;
}
};
将有序数组转换为二叉搜索树
leetcode:108. 将有序数组转换为二叉搜索树
递归法
思路
构造二叉树,前序遍历。
升序,左子树在左半边,右子树在右半边。
复杂度分析
时间复杂度:O(N)。遍历一遍数组。
空间复杂度:O(logN)。因为平衡。
注意点
- 注意循环不变量就好了。
代码实现
/**
* 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* traversal(vector<int>& nums,int begin,int end){
if(begin >= end) return NULL;
int mid = (begin + end)/2;
TreeNode* node = new TreeNode(nums[mid]);
// 升序,左子树在左半边,右子树在右半边
node->left = traversal(nums,begin,mid);
node->right = traversal(nums,mid + 1,end);
return node;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return traversal(nums,0,nums.size());
}
};
迭代法
思路
双指针从中间向两边跑,根节点必须是数值大小中不溜的。
代码实现
我的递归想法:
其实也满足平衡树,但不是最平衡,这题只有最平衡的结果才能通过测试。
/**
* 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() == 1) return new TreeNode(nums[0]);
// 找中间节点,构造根节点
int cur = nums.size()/2;
int pre = cur - 1;
TreeNode* root = new TreeNode(nums[cur]);
cur++;
TreeNode* node = root;
while(pre >= 0 || cur < nums.size()){
// cur右移
if(cur < nums.size()){
// 移到叶子节点
while(node->left && node->right){
if(nums[cur] > root->val) node = node->right;
else if(nums[cur] < root->val) node = node->left;
}
if(nums[cur] > node->val) node->right = new TreeNode(nums[cur]);
else if(nums[cur] < node->val) node->left = new TreeNode(nums[cur]);
cur++;
}
// pre左移
if(pre >= 0){
// 移到叶子节点
while(node->left && node->right){
if(nums[pre] > root->val) node = node->right;
else if(nums[pre] < root->val) node = node->left;
}
if(nums[pre] > node->val) node->right = new TreeNode(nums[pre]);
else if(nums[pre] < node->val) node->left = new TreeNode(nums[pre]);
pre--;
}
}
return root;
}
};
把二叉搜索树转换为累加树
leetcode:538. 把二叉搜索树转换为累加树
思路
要求:使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
所以从大到小遍历一遍,记录累加值,每个节点改为累加值。
中序遍历,不过是先右后左。
复杂度分析
时间复杂度:O(logN)。
空间复杂度:O(logN)/O(N)。
注意点
略
代码实现
/**
* 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 sum = 0;
TreeNode* convertBST(TreeNode* root) {
if(!root) return NULL;
root->right = convertBST(root->right);
sum += root->val;
root->val = sum;
root->left = convertBST(root->left);
return root;
}
};

浙公网安备 33010602011771号