Day20:LeedCode 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

654. 最大二叉树

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

  1. 创建一个根节点,其值为 nums 中的最大值。
  2. 递归地在最大值 左边 的 子数组前缀上 构建左子树。
  3. 递归地在最大值 右边 的 子数组后缀上 构建右子树。

返回 nums 构建的 最大二叉树 

 

示例 1:

 

3c71768d544b08a4c1fc10882b1581c3.jpeg

输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。- [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。- 空数组,无子节点。- [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。- 空数组,无子节点。- 只有一个元素,所以子节点是一个值为 1 的节点。- [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。- 只有一个元素,所以子节点是一个值为 0 的节点。- 空数组,无子节点。

 

思路:采用先序遍历,先找到最大数构造root结点,再根据最大数将数组分为左区间和右区间,分别构造左子树和右子树

图解:

00414dc4916f49c3b17c2783d87865d6.png

递归三部曲:

1.确定返回值和参数类型 

传入需要构造树的数组,返回构造的树

2.确定终止条件

当我们传入的数组只有一个数时,说明该数一定构造叶节点,因为本题1 <= nums.length <= 1000

所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。但是我们分割数组后需要考虑数组长度为0的情况

  if(nums.length==1){
        root.val=nums[0];
        return root;
       }

3.确定单层递归逻辑

找到最大数构造根节点,分割数组为左右区间,构造左右子树

 //找到最大的数作为根节点
       int val=nums[0];
       int index=0;
       for(int i=0;i<nums.length;i++){
            if(val<nums[i]){
                val=nums[i];
                index=i;
            }
        }
        root.val=val;
       //构造左子树
    int[]  left_Tree=Arrays.copyOfRange(nums,0,index);
    int[] right_Tree=Arrays.copyOfRange(nums,index+1,nums.length);
    if(left_Tree.length>0)  root.left=constructMaximumBinaryTree(left_Tree);
    if(right_Tree.length>0)  root.right=constructMaximumBinaryTree(right_Tree);

完整代码参考:

class Solution {public TreeNode constructMaximumBinaryTree(int[] nums) {TreeNode root=  new TreeNode(0);;if(nums.length==1){root.val=nums[0];return root;}//找到最大的数作为根节点int val=nums[0];int index=0;for(int i=0;i<nums.length;i++){if(val<nums[i]){val=nums[i];index=i;}}root.val=val;//构造左子树int[]  left_Tree=Arrays.copyOfRange(nums,0,index);int[] right_Tree=Arrays.copyOfRange(nums,index+1,nums.length);if(left_Tree.length>0)  root.left=constructMaximumBinaryTree(left_Tree);if(right_Tree.length>0)  root.right=constructMaximumBinaryTree(right_Tree);return root;}
}

617. 合并二叉树

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

示例 1:

 

66856f28595d62336a7488e90f4366c5.jpeg

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

思路:本题的关键在于如何同时遍历两个二叉树,其实和遍历一个树逻辑是一样的,只不过传入两个树的节点,同时操作。

递归三要素:

1.确认返回值和参数类型

传入两个数的指针,返回合并后的树的指针

2.确定结束条件

当传入其中一颗树的指针为null时,返回另一个树的指针

3.单层递归逻辑

合并两棵树的当前结点,构造左右子树

root.val=root1.val+root2.val;
root.left=mergeTrees(root1.left,root2.left);
root.right=mergeTrees(root1.right,root2.right);

代码参考:

class Solution {public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {if(root1==null)return root2;if(root2==null)return root1;TreeNode root=new TreeNode(0);root.val=root1.val+root2.val;root.left=mergeTrees(root1.left,root2.left);root.right=mergeTrees(root1.right,root2.right);return root;}
}

 

700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

示例 1:

 

cf9e2268f197fce4c0126ecd32e1cd70.jpeg

输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

二叉搜索树的特点是:

二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

递归三部曲:

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

递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。

2.确定终止条件:

当我们遇到空结点说明找不到该数,返回Null

当当前结点的val等于我们要找的数,就返回该节点

 if(root==null) return null;
   if(root.val==val)return root;

3.每层递归逻辑:

如果当前结点数小于目标数,我们search右子树

如果当前结点数大于目标数,我们search左子树

代码参考:

class Solution {public TreeNode searchBST(TreeNode root, int val) {if(root==null) return null;if(root.val==val)return root;if(root.val<val) return searchBST(root.right,val);if(root.val>val) return searchBST(root.left,val);return null;}
}

 

98. 验证二叉搜索树

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左

    子树

    只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

 

示例 1:

 

101099972afad76f4747a2a358a6c55d.jpeg

输入:root = [2,1,3]
输出:true

这道题目比较容易陷入两个陷阱:

陷阱1:

不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。

我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。

陷阱2

样例中最小节点 可能是int的最小值,如果这样使用最小的int来比较也是不行的。

此时可以初始化比较元素为long的最小值。

思路:我们采用中序遍历,二叉搜索树先序遍历的数一定是递增的,用maxValue记录当前最大值,如果当前结点的值不大于maxValue,则返回false,只有当左右子树都为二叉搜索树并且maxValue<当前结点的val,这棵树才为二叉搜索树

图解:

18004084c7b04187b1ec4efede7fb1e7.png

代码参考:

class Solution {long  maxValue=Long.MIN_VALUE;public boolean isValidBST(TreeNode root) {if(root==null)return true;boolean bl=isValidBST(root.left);if(maxValue<root.val){maxValue=root.val;}else return false;boolean br= isValidBST(root.right);return bl&&br;}
}

如果测试数据中有 long的最小值,怎么办?

不可能在初始化一个更小的值了吧。 建议避免 初始化最小值,如下方法取到最左面节点的数值来比较。

用一个结点保存最大值的结点,如果该结点为null,说明之前没有最大值,也就是我们现在遍历到了最左的结点了

 71d51afd804f46eea601d2edbfe17eb4.png

class Solution {TreeNode MaxNode=null;public boolean isValidBST(TreeNode root) {if(root==null)return true;boolean bl=isValidBST(root.left);if(MaxNode!=null&&MaxNode.val>=root.val){return false;}else MaxNode=root;boolean br= isValidBST(root.right);return bl&&br;}
}

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/572449.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Manacher算法学习笔记(洛谷题单 Part 5.3 Manacher)

0.随便说说 字符串学的太差了&#xff0c;每次字符串算法都是学完了就忘&#xff0c;正好上场 c f d i v 1 B cfdiv1B cfdiv1B考了一个 M a n a c h e r Manacher Manacher&#xff0c;就先复习它了。 1.一些概念 子串 ( s u b s t r i n g ) (substring) (substring)&#…

dump文件分析OOM及线程堆栈

OutOfMemoryError (OOM) 如果项目报错&#xff1a; OutOfMemoryError: Java heap space&#xff0c;说明堆内存空间&#xff08;Heap Space&#xff09;中没有足够的空间来分配对象了。 一旦发生 OOM&#xff0c;系统有可能不可用&#xff0c;或者频繁重启。属于非常严重的问题…

kubernetes负载均衡资源-Ingress

一、Ingress概念 1.1 Ingress概念 使用NodePort类型的Service可以将集群内部服务暴露给集群外部客广端,但使用这种类型Service存在如下几个问题。 1、一个端口只能一个服务使用,所有通过NodePort暴露的端口都需要提前规划;2、如果通过NodePort暴露端口过多,后期维护成本太…

语法回顾-《Verilog编程艺术》之数据类型

目录 线网&#xff08;net&#xff09; 变量&#xff08;variable&#xff09; 线网和变量的区别 向量 数组 参考《Verilog 编程艺术》魏家明著 线网&#xff08;net&#xff09; 用于表示结构体&#xff08;如逻辑门&#xff09;之间的连接。除了 trireg 之外&#xff…

基于单片机病房温度监测与呼叫系统设计

**单片机设计介绍&#xff0c;基于单片机病房温度监测与呼叫系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机病房温度监测与呼叫系统设计概要主要涵盖了通过单片机技术实现病房温度的实时监测以及病人呼叫功能…

【启发式算法】同核分子优化算法 Homonuclear Molecules Optimization HMO算法【Matlab代码#70】

文章目录 【获取资源请见文章第4节&#xff1a;资源获取】1. 算法简介2. 部分代码展示3. 仿真结果展示4. 资源获取 【获取资源请见文章第4节&#xff1a;资源获取】 1. 算法简介 同核分子优化算法&#xff08;Homonuclear Molecules Optimization&#xff0c;HMO&#xff09;是…

pytorch+tensorboard

安装依赖 pip install teorboard pip install torch_tb_profiler了解teorboard 记录并可视化标量[组]、图片[组]。 如何使用 第一步:构建模型,记录中间值,写入summarywriter 每次写入一个标量add_scalar 比如: from torch.utils.tensorboard import SummaryWriter wr…

【Linux】进程地址空间详解

前言 在我们学习C语言或者C时肯定都听过老师讲过地址的概念而且老师肯定还会讲栈区、堆区等区域的概念&#xff0c;那么这个地址是指的物理内存地址吗&#xff1f;这里这些区域又是如何划分的呢&#xff1f; 我们在使用C语言的malloc或者C的new函数开辟空间时&#xff0c;开辟…

鸿蒙应用开发学习:用Marquee组件做个跑马灯

一、前言 鸿蒙应用的学习持续进行中&#xff0c;这两天阅读官方的API参考文档&#xff0c;发现一个有趣的组件——Marquee&#xff0c;用它做了个跑马灯&#xff0c;做个学习记录。 二、参考资料 官网文档链接如下&#xff1a; https://developer.huawei.com/consumer/cn/d…

【python分析实战】成本:揭示电商平台月度开支与成本结构占比 - 过于详细 【收藏】

重点关注本文思路&#xff0c;用python分析&#xff0c;方便大家实验复现&#xff0c;代码每次都用全量的&#xff0c;其他工具自行选择。 全文3000字&#xff0c;阅读10min&#xff0c;操作1小时 企业案例实战欢迎关注专栏 每日更新&#xff1a;https://blog.csdn.net/cciehl/…

一键换脸的facefusion

FaceFusion 一个开源换脸软件&#xff0c;提供UI界面&#xff0c;启动后可直接在浏览器上面上传图片进行换脸操作。 电脑环境win10&#xff0c;软件pycharm&#xff0c;需要提前安装好python环境&#xff0c;推荐使用Anaconda3。关注文章下方公共号发送 “ 软件安装包 ”可以获…

ai智能生成文章,6款ai写作工具高效解决

ai智能生成文章已经成为现代写作的重要工具之一。随着技术的不断进步&#xff0c;越来越多的AI写作工具出现在市场上&#xff0c;为写作者们提供了高效解决方案。在本文中&#xff0c;我将介绍5款值得关注的AI写作工具&#xff0c;并探讨它们的特点和优势。 第一款ai写作工具是…