代码随想录二刷 | 二叉树 | 修剪二叉搜索树

代码随想录二刷 | 二叉树 | 修剪二叉搜索树

题目描述

669.修剪二叉搜索树

给定一个二叉搜索树,同时给定最小边界 L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。

在这里插入图片描述
在这里插入图片描述

解题思路

递归法,当遇到root->val < low || root->val > high 的时候直接return NULL,但是[1, 3]区间在二叉搜索树的中可不是单纯的节点3和左孩子节点0就决定的,还要考虑节点0的右子树。

在这里插入图片描述
在上图中我们发现节点0并不符合区间要求,那么将节点0的右孩子 节点2 直接赋给 节点3的左孩子就可以了(就是把节点0从二叉树中移除),如图:

在这里插入图片描述

递归三部曲

  1. 确定递归函数的参数和返回值
    参数:根节点。以及两个值low、high
    返回值:利用返回值来移除节点,TreeNode*

    TreeNode* trimBST(TreeNode* root, int low, int high)
    
  2. 确定递归函数的终止条件
    遇到空节点返回。

    if(root == nullptr) return nullptr;
    
  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 = rimBST(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(roo->right, low ,high); // rot->right接入符合条件的右孩子
    return root;
    

针对下图的情况,移除多余节点的逻辑如下:

在这里插入图片描述

这一步相当于将要移除的节点(节点0)的右孩子(节点2)返回给上一层

	if (root->val < low) {
		TreeNode* right = trimBST(root->right, low, high);  // 寻找符合区间[low, high]的节点
		return right;
	}

如下代码相当于节点3的左孩子把下一层返回的节点0的右孩子(节点2)接住。

root->left = trimBST(root->left, low, high);

此时节点3的左孩子就变成了节点2,将节点0从二叉树中移除了。

代码实现

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;
		}
		
		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;
	}
};
  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值