题目描述
给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树不应该改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在唯一的答案 。所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
问题分析
递归法: 判断当前节点值,如果小于左边界low,左子树一定小于low,那么就只递归节点的右子树,寻找符合[low,high]区间的节点;如果当前节点值大于high,右子树一定大于有边界high,那么就只递归节点的左子树,寻找符合[low,high]区间的节点 ;若当前节点值在[low,high]区间,就要递归左右子树。
迭代法: 处理根节点,让root移动到[low,high]范围内,注意是左闭右闭区间。 由于root已经在[low,high]范围内,左子树所有节点一定小于high,只要处理左子树节点值小于low情况;右子树所有节点值一定大于low,只要处右子树节点值大于high情况。
代码实现
// 编程软件:VS2019
// 参考书籍:代码随想录
#include<iostream>
using namespace std;
// 定义二叉树
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int v):val(v),left(nullptr),right(nullptr){}
};
/*递归法:
* 判断当前节点值如果小于左边界low,左子树一定小于low,那么就只递归节点的右子树,寻找符合[low,high]区间的节点,
* 如果当前节点值大于high,右子树一定大于有边界high,那么就只递归节点的左子树,寻找符合[low,high]区间的节点
* 当前节点值在[low,high],就要继续遍历左右子树
*/
TreeNode* trimBST1(TreeNode* root, int low, int high) {
if (root == NULL) return NULL; // 遇到空节点,直接返回NULL
// 节点值小于low,递归右子树
if (root->val < low) {
TreeNode* right = trimBST1(root->right, low, high);
return right; // 向上一层返回右子树
}
if (root->val > high) {
TreeNode* left = trimBST1(root->left, low, high);
return left; // 向上一层返回左子树
}
// 当前节点值在[low, high],就要继续遍历左右子树
root->left = trimBST1(root->left, low, high);
root->right = trimBST1(root->right, low, high);
return root; // 向上一层返回节点
}
/*
* 迭代法:处理根节点,让root移动到[low,high]范围内,注意是左闭右闭区间。
* 由于root已经在[low,high]范围内,左子树所有节点一定小于high,只要处理左子树节点值小于low情况;
* 右子树所有节点值一定大于low,只要处右子树节点值大于high情况。
*/
TreeNode* trimBST2(TreeNode* root, int low, int high) {
if (!root) return NULL; // 空树,直接返回NULL
// 处理根节点,让root移动到[low,high]范围内,注意是左闭右闭区间
while (root != NULL && (root->val<low || root->val>high)) {
if (root->val < low) root = root->right; // 小于low则往右遍历
else root = root->left; // 大于high,往左子树遍历
}
TreeNode* cur = root;
// 此时root已经在[low,high]范围内,左子树所有节点一定小于high,只要处理左子树节点值小于low情况
while (cur != NULL) {
while (cur->left && cur->left->val < low) {
cur->left = cur->left->right;
}
cur = cur->left;
}
cur = root;
// 此时root已经在[low,high]范围内,右子树所有节点值一定大于low,只要处右子树节点值大于high情况
while (cur != NULL) {
while (cur->right && cur->right->val > high) {
cur->right = cur->right->left;
}
cur = cur->right;
}
return root;
}
int main() {
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(0);
root->right = new TreeNode(4);
root->left->right = new TreeNode(2);
root->left->right->left = new TreeNode(1);
TreeNode* res = trimBST1(root, 1, 3);
cout << res->val << endl;
}