代码随想录day17 | leetcode 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

news2024/12/14 10:48:36

654.最大二叉树

用中序遍历获取最终的二叉树节点 左闭右开

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return travelMax(nums, 0, nums.length);
    }
    public TreeNode travelMax(int nums[], int left, int right) {
        if(right - left < 1) return null;
        if(right - left == 1) return new TreeNode(nums[left]);
        int maxIndex = left;
        int maxValue = nums[maxIndex];
        for(int i = left; i < right; i++) {
            if(nums[i] > maxValue){
                maxValue = nums[i];
                maxIndex = i;
            }
        }
        TreeNode node = new TreeNode(maxValue);
        node.left = travelMax(nums, left, maxIndex);
        node.right = travelMax(nums, maxIndex + 1, right);
        return node;    
    }
}

在代码中,for 循环中不能将 right 替换成 nums.length,原因是递归函数 travelMax 的逻辑要求在每次递归时处理的是一个特定的子区间,而不是整个数组。下面具体分析:

1. right 是递归的边界

  • 在递归中,travelMax(nums, left, right) 的逻辑是处理 nums 数组的 [left, right) 区间
    • 这个区间是左闭右开,包含 left 但不包含 right
    • 换句话说,right 是当前子区间的结束位置,不代表数组的结束。
  • 如果在循环中写成 nums.length,就会忽略递归中传递的子区间范围。递归时,你希望遍历的是指定子区间 [left, right),而不是整个数组。

2. 子区间范围的递归划分

  • 每次递归,travelMax 会对数组进行划分为左右子区间:- 左子区间:[left, maxIndex)
    • 右子区间:[maxIndex + 1, right)
  • 如果在 for 循环中强制使用 nums.length,就会忽略划分的逻辑,始终遍历整个数组,导致结果不正确。

3. 错误示例分析

如果写成:

for (int i = left; i < nums.length; i++) {
    if (nums[i] > maxValue) {
        maxValue = nums[i];
        maxIndex = i;
    }
}

问题是:

  1. 初始的 travelMax(nums, 0, nums.length) 会遍历整个数组,这是正确的。
  2. 但递归调用时,比如 travelMax(nums, 0, maxIndex),你希望只遍历 [0, maxIndex),但仍会遍历整个数组,导致逻辑混乱,可能访问不属于当前区间的元素。

4. 正确逻辑

for 循环中使用当前递归区间的边界 [left, right),例如:

for (int i = left; i < right; i++) {
    if (nums[i] > maxValue) {
        maxValue = nums[i];
        maxIndex = i;
    }
}
  • 这样可以确保 travelMax 函数只处理当前子区间的元素,且不会访问超出区间的部分。
  • 每次递归都会通过 travelMax(nums, left, maxIndex)travelMax(nums, maxIndex + 1, right) 进一步缩小范围,逐步构建树的左右子树。

总结

right 是当前递归处理的子区间的结束位置,其值可能小于 nums.length。将 right 写成 nums.length 会破坏递归逻辑,导致代码无法正确处理子区间,从而影响结果。

617.合并二叉树

前序遍历合并 实现起来还是很简单的

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null) return root2;
        if(root2 == null) return root1;

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

详细说明:

  1. 判断空树
    • 如果 root1 为空,说明 root1 没有树,那么合并结果直接返回 root2
    • 如果 root2 为空,说明 root2 没有树,那么合并结果直接返回 root1
  2. 合并节点值
    • 如果两个节点都不为空,就将 root1 的值与 root2 的值相加,即 root1.val += root2.val,表示合并这两个节点。
  3. 递归合并左子树和右子树
    • 递归地合并 root1 的左子树和 root2 的左子树,root1.left = mergeTrees(root1.left, root2.left)
    • 同理,递归地合并右子树 root1.right = mergeTrees(root1.right, root2.right)
  4. 返回合并后的树
    • 最后,返回更新后的 root1,这棵树就是合并后的结果。

700.二叉搜索树中的搜索

因为二叉搜索树的特性 导致迭代法也很简单

错误的迭代写法

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while(root != null) {
            if(val < root.val) root = root.left;
            if(val > root.val) root = root.right;
            else return root;
        }
    }
}
问题:

ifelse 之间没有 else if 或明确的分支条件。这样,在某些情况下,val == root.val 也会被进入到 root = root.right 的分支(因为没有 else if),导致错误地更新了 root,即使找到了目标节点。

解决方法:

if(val > root.val)elseelse if 连接,确保只有在 val < root.val 时,才向左子树移动,只有在 val > root.val 时,才向右子树移动,else 才表示找到了目标节点。

正确代码

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while (root != null) {
            if (val < root.val) {
                root = root.left;
            } else if (val > root.val) {
                root = root.right;
            } else {
                return root; // 找到了值等于 val 的节点
            }
        }
        return null; // 没有找到目标值,返回 null 必须写
    }
}

迭代法 要新建树 空间复杂度较高

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val) return root;
        TreeNode result = null;

        if(val < root.val) result = searchBST(root.left, val);
        if(val > root.val) result = searchBST(root.right, val);
        return result;
    }
}

验证二叉搜索树

递归法

class Solution {
    // 递归
    TreeNode max;
    public boolean isValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        // 左
        boolean left = isValidBST(root.left);
        if (!left) {
            return false;
        }
        // 中
        if (max != null && root.val <= max.val) {
            return false;
        }
        max = root;
        // 右
        boolean right = isValidBST(root.right);
        return right;
    }
}

关键点:

  • 中序遍历的顺序:在 BST 中,中序遍历的结果应该是严格递增的序列。- 检查过程中通过比较当前节点值和 max 的值来判断是否满足递增性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

016 在路由器上配置 DHCP

配置路由器端口IP地址 将路由器的端口地址配置好&#xff0c; 左边的网络地址是 192.168.1.0 右边的网络地址是 192.168.2.0 配置路由器的DHCP服务 打开命令窗口&#xff0c;进入特权模式 进入全局配置 conf t创建一个DHCP地址池&#xff1b; po1 是地址池的名称&#xf…

使用IP自签名SSL证书

最近需要创建WebSocket服务器并使用SSL证书&#xff0c;由于是内网测试&#xff0c;所以需要使用指定IP的自签SSL证书。 其实笔者前面博文 使用nexus3作为Docker镜像仓库 解决nexus3登录x509: certificate has expired or is not yet valid 中有创建过相应的证书&#xff0c;这…

多模态大模型(二)——用Transformer Encoder和Decoder的方法(BLIP、CoCa、BEiTv3)

文章目录 BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation 理解、生成我都要&#xff0c;一个很有效的、根据图片生成caption的工具1. BLIP的研究动机2. BLIP的模型结构3. CapFilt Model4. BLIP的训练过程 CoCa: C…

vue季度选择器(antd2.0 版本无此控件,单独写一个)

vue季度选择器 效果显示 效果显示 <template><div><a-popoverplacement"bottom"overlayClassName"season-picker"trigger"click"v-model"showSeason"><template #content><div class"season-picker-b…

基于Spring Boot + Vue的摄影师分享交流社区的设计与实现

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

利用GeoWave导入矢量数据到HBase/Accumulo数据库

前言 最近在做有关地理时空大数据的实验&#xff0c;本文将介绍如何利用geowave框架&#xff0c;将矢量数据导入到HBase或Accumulo等NoSQL数据库中。 软件版本&#xff1a; Hadoop: 2.10.2 Zookeeper: 3.6.4 geowave: 1.2.0 Accumulo&#xff1a;1.9.3 HBase: 1.4.0 Ja…

常回家看看之Tcache Stashing Unlink Attack

前言&#xff1a; 在开始了解这个攻击手法的前提&#xff0c;需要先了解一个函数也就是calloc函数&#xff0c;众所周知&#xff0c;当libc版本大于等于2.27的时候会引入tcachebin&#xff0c;而Tcache Stashing Unlink Attack就是发生在2.27版本以上&#xff0c;那么这个和ca…

心情追忆- SEO优化提升用户发现率

之前&#xff0c;我独自一人开发了一个名为“心情追忆”的小程序&#xff0c;旨在帮助用户记录日常的心情变化及重要时刻。我从项目的构思、设计、前端&#xff08;小程序&#xff09;开发、后端搭建到最终部署。经过一个月的努力&#xff0c;通过群聊分享等方式&#xff0c;用…

深入探索:createThread与cancelThread的用法及实例

在多线程编程领域,线程的创建与管理是核心技能之一。本文将详细介绍两个关键函数:createThread(用于创建新线程)和cancelThread(用于取消已存在的线程),并通过具体实例展示它们的用法。需要注意的是,不同的编程语言和线程库可能有不同的API设计,但基本概念是相通的。本…

Cherno C++学习笔记 P36 初始化类成员

这一篇文章我们主要讲一下如何初始化类成员&#xff0c;并给出一个初始化类成员的小技巧。我们都知道&#xff0c;我们会使用构造函数来初始化我们的类成员变量。 首先我们来举一个简单的小例子&#xff0c;展现一下构造函数的功能&#xff1a; #include<iostream> #in…

快速解决git@github.com: Permission denied (publickey)

在使用github进行项目克隆的时候&#xff0c;有些时候会出现“gitgithub.com: Permission denied (publickey)”的错误。这个问题大部分是由于新设备本地密钥未加入gitbub列表中&#xff0c;我们可以通过加入新机器身份验证解决问题。 一、问题现象 二、问题解决 2.1&#xf…

移动端h5自适应rem适配最佳方案

网页开发中&#xff0c;我们常用的单位有如下几个&#xff1a; px&#xff1a;像素固定&#xff0c;无法适配各分辨率的移动设备em: 该单位受父容器影响&#xff0c;大小为父元素的倍数rem: 因为html根元素大小为16px&#xff0c;所以默认 1rem 16px&#xff0c;rem只受根元素…

C语言程序设计P5-5【应用函数进行程序设计 | 第五节】—知识要点:变量的作用域和生存期

知识要点&#xff1a;变量的作用域和生存期 视频&#xff1a; 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 有一个一维数组&#xff0c;内放 10 个学生成绩&#xff0c;写一个函数&#xff0c;求出平均分、最高分和最低分。 任务要求用一个函数来完…

Jenkins与SonarQube持续集成搭建及坑位详解

Jenkins和SonarQube都是软件开发过程中常用的工具,它们在代码管理、构建、测试和质量管理方面发挥着重要作用。以下是关于Jenkins与SonarQube的作用及整合步骤环境搭建的详细解释: 一、Jenkins与SonarQube的作用 Jenkins: Jenkins是一个开源的持续集成和交付工具,它可以帮…

item2 for macos

安装Item2 brew install iterm2 查看终端类型 cat /etc/shells Mac OS X 10.15 已经将默认的shell从Bash换成了zsh&#xff0c;所以不用安装&#xff0c;10.15以前的可以使用下面的命令进行安装 brew install zsh 安装Oh My ZSH # curl sh -c "$(curl -fsSL https://ra…

[搜广推]王树森推荐算法——基于物体的协同过滤

基于物体的协同过滤 ItemCF 基于物体的协同过滤&#xff08;Item-Based Collaborative Filtering&#xff0c;简称ItemCF&#xff09;是一种经典的推荐系统算法 基本思想 量化用户对物品的兴趣&#xff0c;通过分析用户的行为来找到与目标物品相似的其他物品&#xff0c;然后…

3D 生成重建035-DiffRF直接生成nerf

3D 生成重建035-DiffRF直接生成nerf 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 本文提出了一种基于渲染引导的三维辐射场扩散新方法DiffRF&#xff0c;用于高质量的三维辐射场合成。现有的方法通常难以生成具有细致纹理和几何细节的三维模型&#xff0c;并且容易出…

计算机毕业设计Python+CNN卷积神经网络高考推荐系统 高考分数线预测 高考爬虫 协同过滤推荐算法 Vue.js Django Hadoop 大数据毕设

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

linux - 存储管理

1.了解硬件 -- 磁盘 硬盘有机械硬盘(HDD)和固态硬盘(SDD) 接下来&#xff0c;主要以机械磁盘为例(更具代表性&#xff0c;在linux系统层面&#xff0c;无论是机械磁盘还是固态硬盘&#xff0c;文件的读取和写入都iNode(索引节点)管理文件的元数据和实际数据块) 1.盘片&#x…

打造高效的HIS与DAT文件解析工具

在工业数据采集和存储中&#xff0c;HIS 和 DAT 文件是非常常见的二进制数据格式。然而&#xff0c;解析这些固定块大小的二进制文件并将其转换为易读的 CSV 格式并非易事。本文将深入讲解如何使用 Python 和 PyQt5 打造一款图形化工具&#xff0c;轻松解析和转换这些文件&…