力扣:669. 修剪二叉搜索树

题目描述

给你二叉搜索树的根节点 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeKwang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值