首页 > 其他分享 >【LeetCode二叉树#18】修剪二叉搜索树(涉及重构二叉树与递归回溯)

【LeetCode二叉树#18】修剪二叉搜索树(涉及重构二叉树与递归回溯)

时间:2023-03-05 20:11:47浏览次数:60  
标签:遍历 TreeNode 递归 18 LeetCode 二叉树 root 节点 low

修剪二叉搜索树

力扣题目链接(opens new window)

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

669.修剪二叉搜索树 669.修剪二叉搜索树1

思路

题目描述得有点唬人,其实意思就是给一个区间范围(比如[2, 7]),然后要求你把节点值不在这个范围内的节点给删除掉,并且之后还是二叉搜索树

一种经典的错误思路是:遇到不符合区间的节点时,直接返回NULL给上一个节点

这样做的话,如果不满足条件的节点的子树还有满足条件的值的话,也会被舍弃,从而出错

当我们找到一个不在规定范围内的节点时,首先要判断它是小于范围还是大于范围

如果节点(假设为A)的值小于规定范围,根据二叉搜索树的性质,其右子树有可能还存在满足规定范围的节点,因此需要继续遍历其右子树

如果节点(假设为A)的值大于规定范围,根据二叉搜索树的性质,其左子树有可能还存在满足规定范围的节点,因此需要继续遍历其左子树

基本思路是这样的

下面来看代码

代码

还是使用递归法来做

1、确定递归函数的参数和返回值

参数肯定是根节点啦,因为我们需要修改二叉树,所以修改的新值需要层层传递到上层递归的调用处,因此需要返回值

那么可以直接用解题模板

class Solution {
public:
    //确定递归函数的参数和返回值
    TreeNode* trimBST(TreeNode* root, int low, int high) {

    }
};

2、确定终止条件

如果当前输入的节点为空,那么应该返回空并结束递归

class Solution {
public:
    //确定递归函数的参数和返回值
    TreeNode* trimBST(TreeNode* root, int low, int high) {
		//确定终止条件
        if(root == NULL) return NULL;
    }
};

3、确定单层处理逻辑

当前节点小于规定范围时,遍历其右子树

class Solution {
public:
    //确定递归函数的参数和返回值
    TreeNode* trimBST(TreeNode* root, int low, int high) {
		//确定终止条件
        if(root == NULL) return NULL;
        
        //确定单层递归逻辑
        if(root->val < low){//遍历其右子树
            TreeNode* right = trimBST(root->right, low, high);
            return right;
        }
    }
};

解释一下递归右子树的代码的含义

上面那样写的意思是:使用当前节点作为根节点,递归遍历其右子树,最后返回一颗经过修剪的满足条件的右子树

实在不理解或者忘了,可以自己模拟一下过程

同理,当前节点大于规定范围时,遍历其左子树

class Solution {
public:
    //确定递归函数的参数和返回值
    TreeNode* trimBST(TreeNode* root, int low, int high) {
		//确定终止条件
        if(root == NULL) return NULL;
        
        //确定单层递归逻辑
        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;
        
    }
};

注意,这里我们要搜索的是当前节点的左子树或右子树(是整颗树)

还是模拟一下过程把怕之后看又不记得了

首先我们将根节点输入到递归函数中,此时其不满足递归结束的条件,假设其值也在规定范围内

那么此时会调用递归,去遍历根节点的左右子树【第一层递归,希望返回的是一颗修剪后的左或右子树

然后进入左子树,若当前左子树的根节点不在规定范围内,则触发对应的单层处理逻辑

假设此时触发的是root->val < low条件,那么回去递归遍历当前左子树根节点的右子树【第二层递归,希望返回的是一颗修剪后的右子树

假设其右子树均满足规定范围,那么当递归遍历到叶子节点后,会触发终止条件,然后每层递归都往上返回自己的结果,从而得到修改后的树

标签:遍历,TreeNode,递归,18,LeetCode,二叉树,root,节点,low
From: https://www.cnblogs.com/DAYceng/p/17181474.html

相关文章

  • 【LeetCode二叉树#19】有序数组转换为二叉搜索树(构造二叉树)
    将有序数组转换为二叉搜索树力扣题目链接(opensnewwindow)将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。本题中,一个高度平衡二叉树是指一个二叉树每个......
  • MIT 6.1810 Lab:system calls
    lab网址:https://pdos.csail.mit.edu/6.828/2022/labs/syscall.htmlxv6Book:https://pdos.csail.mit.edu/6.828/2022/xv6/book-riscv-rev3.pdfUsinggdb总体感觉,对xv6的调......
  • 力扣-101. 对称二叉树
    题目大意给定一颗二叉树,判断是否对称解题思路将其中一个子树镜像翻转,再判断左右子树相不相等即可。镜像翻转示意图如下:code/***Definitionforabinarytreenod......
  • 代码随想录day18|
    找树左下角的值给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。分析用层序遍历最底层的最左节点  递归记录第一次到达下一层的节......
  • LeetCode 29. Divide Two Integers 题解教程 All In One
    LeetCode29.DivideTwoIntegers题解教程AllInOnehttps://leetcode.com/problems/divide-two-integers/description///functiondivide(dividend:number,divis......
  • 18.JSR303数据校验
    以新增品牌接口为例接口代码展示   添加校验注解前端送的json对应BrandEntity,比如我们需要品牌的名称不能为空:  NotBlank注解表示不允许为null为空为纯空......
  • 【LeetCode二叉树#17】在二叉搜索树中插入或删除某个值(涉及重构二叉树、链表基础、以
    二叉搜索树中的插入操作力扣题目链接(opensnewwindow)给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。返回插入后二叉搜索树的根节点。输入数据保证......
  • 二叉树遍历的操作与实现
    先序遍历先序遍历(递归版)代码展示/*先序遍历(递归版)*/StatusPreOrderTraverse(BiTreeT,StatusVisit(TElemTypee)){ if(T) { Visit(T->data); PreOrderTra......
  • csp201803-2
    主要思路就是:如果存在位置相同的两球,那么其前进方向*-1;或者球在端点,*-1,按时间累加即可。#include<bits/stdc++.h>usingnamespacestd;inta[105];intflag[105];int......
  • 12月将发布 Linux Mint 18.1″Serena” 公测版
    ​​Linux​​ Mint在月度简报上,LinuxMint负责人ClementLefebvre重申强调了关于即将到来LinuxMint18.1“Serena”操作系统的相关信息。该发行版本目前仍在开发进程中,......