首页 > 其他分享 >代码随想录第20天| 654.最大二叉树 617.合并二叉树

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

时间:2024-03-25 23:03:36浏览次数:26  
标签:20 nums 随想录 二叉树 leftIndex root1 节点 root2

 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;
    }
}

标签:20,nums,随想录,二叉树,leftIndex,root1,节点,root2
From: https://blog.csdn.net/lilith_2001/article/details/137023957

相关文章

  • 代码随想录第18天 | 513.找左下角的值 112.路径总和
    513.找左下角的值513.找树左下角的值-力扣(LeetCode)代码随想录(programmercarl.com)怎么找二叉树的左下角?递归中又带回溯了,怎么办?|LeetCode:513.找二叉树左下角的值_哔哩哔哩_bilibili给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。假......
  • [NKCTF 2024]web解析
    文章目录myfirstcms全世界最简单的CTF解法一解法二myfirstcms打开题目在最下面发现是CMSMadeSimple,版本为2.2.19扫一下发现存在后台登陆界面,直接访问用字典爆破下admin的密码为Admin123然后直接登录,去漏洞库搜一下其实存在很多漏洞(重点看最近的)找到CM......
  • 基于LabVIEW上位机与Arduino单片机串口通信的DS18B20环境温度采集
    基于LabVIEW上位机与Arduino单片机串口通信的DS18B20环境温度采集Arduino代码#include<OneWire.h>#include<DallasTemperature.h>#defineONE_WIRE_BUS2//DS18B20接至Arduino数字口2OneWireoneWire(ONE_WIRE_BUS);DallasTemperaturesensors(&oneWire);byteco......
  • 给 zqx 的生日祝福(2024)
    zqx:首先,生日快乐!2024年3月26日0:00(UTC+8)的钟声敲响的那刻,你就成为了一个可爱的\(16(=2^{4})\)岁的女孩子啦!(抱住)自从上高中之后,sk和你见面的次数好像屈指可数(?),主要是sk的训练计划的原因(甚至一个寒假都几乎不在南宁),不过寄信还是相对比较多的(?)。如果预先知道zqx的信要到......
  • 【毕业设计选题】2024年 计算机专业毕设选题推荐合集 毕设指导
    目录前言网站开发/管理系统类小程序开发/公众号类深度学习、机器学习类算法研究方向物联网应用、嵌入式方向信息安全、网络安全大数据分析、大数据预测Matlab选题迷茫选题的重要性选题指导前言对毕设有任何疑问都可以问学长哦!    大四是整个大学期间最......
  • 2023ICPC沈阳区域赛I题Three Rectangles补题
    题意有一个(0,0)(左下角)到(H,W)(右上角)的矩形区域,给出3个小矩形的h和w,要求3个矩形盖住矩形区域的放置方案:要求3个矩形不能旋转,只能放到整点上,不能超出矩形区域,可以重叠。mod1e9+7。H,W范围1e9,\(1\leqh_i\leqH,1\leqw_i\leqW\)分析及实现由3个小矩形盖住大矩形,通过思考......
  • 2017 各省省选做题笔记
    AHOI/HNOID1T1单旋不会哦,感觉这题最难。D1T2影魔考虑计算每个位置作为\([l+1,r-1]\)中的最大值时的贡献,一定是有一端取到了左边第一个比自己大的或者右边第一个比自己大的,可以用单调栈求出所有的有效点对,是线性的,然后做一遍二维数点即可。D1T3礼物首先考虑不做修......
  • UNIQUE VISION Programming Contest 2024 Spring(AtCoder Beginner Contest 346)
    C我们用\(1\simK\)的和减去出现在\(1\simK\)中的数的和。intn,k,a[N],res;map<int,int>vis;signedmain(){ cin>>n>>k; _for(i,1,n)cin>>a[i]; res=k*(1+k)/2; _for(i,1,n)if(a[i]>=1&&a[i]<=......
  • 20240325打卡
    第五周第一天第二天第三天第四天第五天第六天第七天所花时间20h代码量(行)877博客量(篇)1知识点了解navigation路由配置,jetpackcompose组件运用,容器封装......
  • 把握机遇:2024年游戏行业春招提前批全攻略
    当前,国内游戏行业正处于高速发展期,各大游戏公司对应届毕业生的人才需求十分旺盛。这一趋势不仅为即将步入职场的学生们提供了广阔的就业前景,也为游戏产业的创新和多元化发展注入了新鲜血液。在这样的大环境下,2024年春季提前批招聘无疑为应届毕业生提供了难得的就业机会。提前......