代码随想录第20天| 654.最大二叉树 617.合并二叉树

 654.最大二叉树

654. 最大二叉树 - 力扣(LeetCode)

代码随想录 (programmercarl.com)

又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树_哔哩哔哩_bilibili

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

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

返回 nums 构建的 最大二叉树 

示例 1:

输入: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 的节点。
        - 空数组,无子节点。

示例 2:

输入:nums = [3,2,1]
输出:[3,null,2,null,1]

提示:

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000
  • nums 中的所有整数 互不相同

这个题一开始读题没怎么读懂且有非常多的疑惑,比如最大值不在中间在两端的话怎么办?那这棵树是不是就瘸了?比如左右子树怎么构造?是不是要比较大小?

于是我就去看卡哥题解了。看了发现我没抓住重点。比如这个题的遍历方式应该为前序遍历,而且构造树的遍历方式都应该为前序遍历。这是因为构造树的时候需要先构造根节点,然后左右孩子才有着陆点。

递归三部曲:

1、确定参数和返回值:参数传入的是存放数值的元组,返回类型是指向节点的指针

class Solution{
    public TreeNode constructMaximumBinaryTree(int[] nums){
        return constructMaximumBinaryTree1(nums, 0, nums.length);
    }    
}

2、确定终止条件:当递归遍历的时候,数组大小为1时,说明遍历到了叶子节点,终止遍历。

// 如果右边界索引减左边界索引等于 1,说明只有一个元素,返回包含该元素的新节点
if (rightIndex - leftIndex == 1) {
    return new TreeNode(nums[leftIndex])
}

3、确定单层递归的逻辑:

先找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组。

public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex){
    if(rightIndex - leftIndex < 1){
        return null;
    }
    if(rightIndex - leftIndex == 1){
        return new TreeNode(nums[leftIndex]);
    }
    int maxIndex = leftIndex;
    int maxVal = nums[maxIndex];
    for(int i = leftIndex + 1; i < rightIndex; i++){
        if(nums[i] > maxVal) {
            maxVal = nums[i];
            maxIndex = i;
        }
    }
}

最大值所在的下标左区间 构造左子树;最大值所在的下标右区间 构造右子树

        TreeNode root = new TreeNode(maxVal);
        // 根据maxIndex划分左右子树
        root.left = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
        root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
        return root;

综合代码:

class Solution {
    // 构建最大二叉树的入口函数,传入整数数组 nums
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        // 调用辅助函数 constructMaximumBinaryTree1,传入数组 nums、左边界索引 0 和右边界索引 nums.length
        return constructMaximumBinaryTree1(nums, 0, nums.length);
    }

    // 辅助函数,用于构建最大二叉树,传入数组 nums、左边界索引 leftIndex 和右边界索引 rightIndex
    public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex) {
        // 如果右边界索引减左边界索引小于 1,说明没有元素了,返回 null
        if (rightIndex - leftIndex < 1) {
            return null;
        }
        // 如果右边界索引减左边界索引等于 1,说明只有一个元素,返回包含该元素的新节点
        if (rightIndex - leftIndex == 1) {
            return new TreeNode(nums[leftIndex]);
        }
        // 初始化最大值所在位置为左边界索引,最大值为对应位置的数组元素
        int maxIndex = leftIndex;
        int maxVal = nums[maxIndex];
        // 遍历数组,找到最大值及其所在位置
        for (int i = leftIndex + 1; i < rightIndex; i++) {
            if (nums[i] > maxVal) {
                maxVal = nums[i];
                maxIndex = i;
            }
        }
        // 创建根节点,值为最大值
        TreeNode root = new TreeNode(maxVal);
        // 根据最大值所在位置将数组划分为左右两部分,分别递归构建左右子树
        root.left = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
        root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
        return root; // 返回根节点
    }
}

 

617.合并二叉树 

617. 合并二叉树 - 力扣(LeetCode)

代码随想录 (programmercarl.com)

一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili

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

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

返回合并后的二叉树。

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

示例 1:

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

示例 2:

输入:root1 = [1], root2 = [1,2]
输出:[2,2]

提示:

  • 两棵树中的节点数目在范围 [0, 2000] 内
  • -104 <= Node.val <= 104

第一想法是将两个二叉树同时遍历,如果相同位置都有值则把同位置的值相加后放到新二叉树的同一位置上;如果同一位置上,有一颗二叉树没有值,则把另外一个有值的值放到新二叉树的对应位置上。但是代码实现没想法。

看了题解:

递归三部曲:

1、确定参数和返回值:参数是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。

public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
    return root1;
}

2、确定终止条件:

因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。

反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。

// 如果root1为空,返回root2,表示以root2为基准进行合并
        if (root1 == null) return root2;
        // 如果root2为空,返回root1,表示以root1为基准进行合并
        if (root2 == null) return root1;

3、确定单层递归的逻辑:

// 将root2的值加到root1的值上
        root1.val += root2.val;
        // 递归合并左子树,将合并结果赋给root1的左子树
        root1.left = mergeTrees(root1.left, root2.left);
        // 递归合并右子树,将合并结果赋给root1的右子树
        root1.right = mergeTrees(root1.right, root2.right);
        // 返回合并后的root1树
        return root1;

综合代码:

class Solution {
    // 定义一个类Solution,用于解决问题
    // 递归函数,合并两棵二叉树,参数为树的根节点root1和根节点root2
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        // 如果root1为空,返回root2,表示以root2为基准进行合并
        if (root1 == null) return root2;
        // 如果root2为空,返回root1,表示以root1为基准进行合并
        if (root2 == null) return root1;

        // 将root2的值加到root1的值上
        root1.val += root2.val;
        // 递归合并左子树,将合并结果赋给root1的左子树
        root1.left = mergeTrees(root1.left, root2.left);
        // 递归合并右子树,将合并结果赋给root1的右子树
        root1.right = mergeTrees(root1.right, root2.right);
        // 返回合并后的root1树
        return root1;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python+selenium做ui自动化测试用法必会

一、前言 大家都知道&#xff0c;基于Web端的测试的基础框架是需要Selenium做主要支撑的&#xff0c;这里边给大家介绍下Web测试核心之基于Python的Selenium Selenium是用于测试Web应用程序用户界面(UI)的常用框架。它是一款用于运行端到端功能测试的超强工具。您可以使用多个编…

ExperimentalWarning: The http2 module is an experimental API.

错误提示 Node.js:ExperimentalWarning: The fs.promises API is experimental原因是node的版本不是最新的&#xff0c;而在项目引入的模块是最新的&#xff0c;node.js的版本低于模块的版本&#xff1a; 解决方法: 1、升级版本 npm install -g npm 更新npm到最新版 npm ins…

MyBatis3源码深度解析(二十一)动态SQL实现原理(二)动态SQL解析过程、#{}和${}的区别

文章目录 前言8.5 动态SQL解析过程8.5.1 SQL配置转换为SqlSource对象8.5.2 SqlSource转换为静态SQL语句 8.6 #{}和${}的区别8.7 小结 前言 在【MyBatis3源码深度解析(二十)动态SQL实现原理(一)动态SQL的核心组件】中研究了MyBatis动态SQL相关的组件&#xff0c;如SqlSource用于…

vue.js制作学习计划表案例

通俗易懂&#xff0c;完成“学习计划表”用于对学习计划进行管理&#xff0c;包括对学习计划进行添加、删除、修改等操作。 一. 初始页面效果展示 二.添加学习计划页面效果展示 三.修改学习计划完成状态的页面效果展示 四.删除学习计划 当学习计划处于“已完成”状态时&…

Linux基础-Makefile

目录 一、Make简介 二、Makefile基本结构 示例&#xff1a; 补充(Makefile)&#xff1a; 伪目标&#xff1a; 三、创建和使用变量 变量定义的方式&#xff1a; 简单方式&#xff1a; 递归方式&#xff1a; 用?定义变量 为变量添加值 预定义变量 例 自动变量 例…

C++函数模板详解(结合代码)

目录 1. 模板概念 2. 函数模板语法 3. 函数模板注意事项 4. 函数模板案例 5. 普通函数与函数模板的区别 6. 普通函数与函数模板的调用规则 7. 模板的局限性 1. 模板概念 在C中&#xff0c;模板是一种通用的程序设计工具&#xff0c;它允许我们处理多种数据类型而不是固…

【STM32嵌入式系统设计与开发】——9Timer(定时器中断实验)

这里写目录标题 一、任务描述二、任务实施1、ActiveBeep工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#xff08;2&#xff09;USART1初始化函数(usart1_init())&#xff08;3&#xff09;USART数据发送函数&#xff08; USART1_Send_Data&#xff08;&…

【Java基础知识总结 | 第六篇】Java反射知识总结

文章目录 6.Java反射知识总结6.1概述6.1.1什么是反射&#xff1f;6.1.2为什么使用反射&#xff1f; 6.2反射的原理6.3反射的使用6.3.1获取类对象&#xff08;1&#xff09;通过具体类的类名获取&#xff08;2&#xff09;通过对象实例获取&#xff08;3&#xff09;通过class.f…

正式发布:VitePress 1.0 现代化静态站点生成器!

大家好&#xff0c;我是奇兵&#xff0c;今天介绍一下现代化静态站点生成器!&#xff0c;希望能帮到大家。 3 月 21 日&#xff0c; 由 Vue 团队出品的现代化静态站点生成器 VitePress 正式发布 1.0 版本&#xff01;它专为构建快速、以内容为中心的网站而生&#xff0c;能够轻…

Django之Celery篇(一)

一、介绍 Celery是由Python开发、简单、灵活、可靠的分布式任务队列,是一个处理异步任务的框架,其本质是生产者消费者模型,生产者发送任务到消息队列,消费者负责处理任务。 Celery侧重于实时操作,但对调度支持也很好,其每天可以处理数以百万计的任务。特点: 简单:熟悉…

获取Book里所有sheet的名字,且带上超链接

应用背景&#xff1a; 当一个excel有很多sheet的时候&#xff0c;来回切换sheet会比较复杂&#xff0c;所以我希望excel的第一页有目录&#xff0c;可以随着sheet的增加&#xff0c;减少&#xff0c;改名而随时可以去更新&#xff0c;还希望有超链接可以直接跳到该sheet。 可以…

VPCFormer:一个基于transformer的多视角指静脉识别模型和一个新基准

文章目录 VPCFormer:一个基于transformer的多视角指静脉识别模型和一个新基准总结摘要介绍相关工作单视角指静脉识别多视角指静脉识别Transformer 数据库基本信息 方法总体结构静脉掩膜生成VPC编码器视角内相关性的提取视角间相关关系提取输出融合IFFN近邻感知模块(NPM) patch嵌…

ssm006基于java的少儿编程网上报名系统+vue

少儿编程网上报名系统 摘 要 在国家重视教育影响下&#xff0c;教育部门的密确配合下&#xff0c;对教育进行改革、多样性、质量等等的要求&#xff0c;使教育系统的管理和运营比过去十年前更加理性化。依照这一现实为基础&#xff0c;设计一个快捷而又方便的网上少儿编程网上…

pdf压缩文件怎么压缩最小?一键压缩PDF

pdf文件压缩是为了减小文件大小&#xff0c;以便更轻松地共享、传输和存储文件&#xff0c;通过压缩pdf文件&#xff0c;可以减少文件占用的存储空间&#xff0c;加快文件的上传和下载速度&#xff0c;并节省带宽和存储成本;在本教程中&#xff0c;我们将介绍一些有效的方法来最…

如何自定义一个starter?

在Spring Boot中&#xff0c;创建一个自定义starter可以简化特定功能或组件的配置过程&#xff0c;让其他项目能够轻松地重用这些功能。 一、问题解析 这里我们以自定义一个xxl-job的starter为例&#xff0c;介绍下如何简化配置。 添加依赖 添加Spring Boot的依赖&#xff1a…

关于网格数据导出指定格式的测试(以Gmsh导出nas格式为例)

本文主要讲述Gmsh如何导出nas格式的网格数据&#xff0c;众所周知&#xff0c;Gmsh可以导出多种网格数据格式&#xff0c;比如大家熟悉的msh、stl、inp、cgns&#xff08;似乎不完善&#xff09;等等&#xff0c;但是gmsh不支持nas格式的导出&#xff0c;只支持nas格式的导入&a…

Bug定位与分析,软件测试员你中招了吗?

之所以写这一篇文章&#xff0c;是突然想起来曾经在测试过程中被开发嘲讽过&#xff0c;事情是这样的&#xff0c;当时发现了一个疑似前端的Bug就草草提交到了禅道&#xff0c;结果刚来的女前端看到了就有点生气地问我为啥不查清到底是前后端问题就直接派给她前端了&#xff0c…

睿考网:不是会计专业能考中级会计师吗?

不是会计专业也是可以考中级会计师的&#xff0c;中级会计师报名条件中并没有对专业做明确的限制&#xff0c;不同的学历对工作年限的要求不一样&#xff0c;如果考生满足报考条件就可以参加。 1.具备大学专科学历&#xff0c;从事会计工作满5年。 2.具备大学本科学历或学士学…

大数据Doris(七十):全球电商狂欢节万亿级实时大屏解决方案

文章目录 全球电商狂欢节万亿级实时大屏解决方案 一、背景介绍 <