news 2026/5/16 4:49:42

搜索题目:验证二叉树

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
搜索题目:验证二叉树

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 前言
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法三
    • 预备知识
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:验证二叉树

出处:1361. 验证二叉树

难度

6 级

题目描述

要求

n \texttt{n}n个二叉树结点,从0 \texttt{0}0n − 1 \texttt{n} - \texttt{1}n1编号,其中结点i \texttt{i}i的两个子结点分别是leftChild[i] \texttt{leftChild[i]}leftChild[i]rightChild[i] \texttt{rightChild[i]}rightChild[i]。当且仅当所有结点形成恰好一个有效的二叉树时,返回true \texttt{true}true

如果结点i \texttt{i}i没有左子结点,那么leftChild[i] \texttt{leftChild[i]}leftChild[i]等于-1 \texttt{-1}-1。右子结点也符合该规则。

注意:结点没有值,这道题中仅使用结点编号。

示例

示例 1:

输入:n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1] \texttt{n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]}n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]
输出:true \texttt{true}true

示例 2:

输入:n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1] \texttt{n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]}n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]
输出:false \texttt{false}false

示例 3:

输入:n = 2, leftChild = [1,0], rightChild = [-1,-1] \texttt{n = 2, leftChild = [1,0], rightChild = [-1,-1]}n = 2, leftChild = [1,0], rightChild = [-1,-1]
输出:false \texttt{false}false

数据范围

  • n = leftChild.length = rightChild.length \texttt{n} = \texttt{leftChild.length} = \texttt{rightChild.length}n=leftChild.length=rightChild.length
  • 1 ≤ n ≤ 10 4 \texttt{1} \le \texttt{n} \le \texttt{10}^\texttt{4}1n104
  • -1 ≤ leftChild[i], rightChild[i] ≤ n − 1 \texttt{-1} \le \texttt{leftChild[i], rightChild[i]} \le \texttt{n} - \texttt{1}-1leftChild[i], rightChild[i]n1

前言

给定的n nn个结点以及左右子结点的关系可以看成有向图。如果有向图的所有结点形成恰好一个有效的二叉树,则应满足以下条件。

  1. 边数等于n − 1 n - 1n1

  2. 只有根结点的入度是0 00,其余n − 1 n - 1n1个结点的入度都是1 11

  3. 全部结点和边组成连通无环图。

条件 1 和条件 2 可以通过遍历图中的全部边判断。具体而言,对于0 ≤ i < n 0 \le i < n0i<n,如果leftChild [ i ] ≥ 0 \textit{leftChild}[i] \ge 0leftChild[i]0则存在一条从结点i ii指向结点leftChild [ i ] \textit{leftChild}[i]leftChild[i]的有向边,如果rightChild [ i ] ≥ 0 \textit{rightChild}[i] \ge 0rightChild[i]0则存在一条从结点i ii指向结点rightChild [ i ] \textit{rightChild}[i]rightChild[i]的有向边。

遍历全部边之后,如果不满足条件 1 或条件 2,则有向图的所有结点一定不能形成恰好一个有效的二叉树,返回false \text{false}false。当以下情况之一出现时,不满足条件 1 或条件 2。

  • 边数不等于n − 1 n - 1n1

  • 不存在入度是0 00的结点,或者有超过1 11个入度是0 00的结点。

  • 存在入度大于1 11的结点。

当条件 1 和条件 2 都满足时,有向图可能由一个二叉树和一个或多个环组成,此时有向图的所有结点不能形成恰好一个有效的二叉树,因此需要判断条件 3 是否满足。由于边数等于结点数少1 11,因此连通图一定无环,只要判断有向图是否连通即可。

可以使用广度优先搜索、深度优先搜索或并查集判断有向图是否连通。

解法一

思路和算法

可以使用广度优先搜索判断有向图是否连通。入度是0 00的结点是根结点,从根结点开始遍历,对于每个结点,如果存在子结点则继续访问子结点。遍历结束时,根据访问的结点数是否等于n nn判断有向图是否连通。

根结点所在的连通分量中一定不存在环,否则会存在入度大于1 11的结点,因此广度优先搜索的过程中不需要记录每个结点是否被访问过。

代码

classSolution{publicbooleanvalidateBinaryTreeNodes(intn,int[]leftChild,int[]rightChild){intedges=0;int[]indegrees=newint[n];for(inti=0;i<n;i++){intleft=leftChild[i],right=rightChild[i];if(left>=0){edges++;indegrees[left]++;}if(right>=0){edges++;indegrees[right]++;}}if(edges!=n-1){returnfalse;}introot=-1;for(inti=0;i<n;i++){if(indegrees[i]==0){if(root<0){root=i;}else{returnfalse;}}elseif(indegrees[i]>1){returnfalse;}}if(root<0){returnfalse;}intvisitCount=0;Queue<Integer>queue=newArrayDeque<Integer>();queue.offer(root);while(!queue.isEmpty()){intnode=queue.poll();visitCount++;intleft=leftChild[node],right=rightChild[node];if(left>=0){queue.offer(left);}if(right>=0){queue.offer(right);}}returnvisitCount==n;}}

复杂度分析

  • 时间复杂度:O ( n ) O(n)O(n),其中n nn是结点数。计算边数和每个结点的入度需要O ( n ) O(n)O(n)的时间,判断每个结点的入度是否符合要求需要O ( n ) O(n)O(n)的时间,广度优先搜索需要O ( n ) O(n)O(n)的时间遍历每个结点最多一次。

  • 空间复杂度:O ( n ) O(n)O(n),其中n nn是结点数。入度数组和队列需要O ( n ) O(n)O(n)的空间。

解法二

思路和算法

也可以使用深度优先搜索判断有向图是否连通。入度是0 00的结点是根结点,从根结点开始遍历,对于每个结点,如果存在子结点则继续访问子结点。遍历结束时,根据访问的结点数是否等于n nn判断有向图是否连通。

根结点所在的连通分量中一定不存在环,否则会存在入度大于1 11的结点,因此深度优先搜索的过程中不需要记录每个结点是否被访问过。

代码

classSolution{intn;int[]leftChild;int[]rightChild;intvisitCount=0;publicbooleanvalidateBinaryTreeNodes(intn,int[]leftChild,int[]rightChild){this.n=n;this.leftChild=leftChild;this.rightChild=rightChild;intedges=0;int[]indegrees=newint[n];for(inti=0;i<n;i++){intleft=leftChild[i],right=rightChild[i];if(left>=0){edges++;indegrees[left]++;}if(right>=0){edges++;indegrees[right]++;}}if(edges!=n-1){returnfalse;}introot=-1;for(inti=0;i<n;i++){if(indegrees[i]==0){if(root<0){root=i;}else{returnfalse;}}elseif(indegrees[i]>1){returnfalse;}}if(root<0){returnfalse;}dfs(root);returnvisitCount==n;}publicvoiddfs(intnode){visitCount++;intleft=leftChild[node],right=rightChild[node];if(left>=0){dfs(left);}if(right>=0){dfs(right);}}}

复杂度分析

  • 时间复杂度:O ( n ) O(n)O(n),其中n nn是结点数。计算边数和每个结点的入度需要O ( n ) O(n)O(n)的时间,判断每个结点的入度是否符合要求需要O ( n ) O(n)O(n)的时间,深度优先搜索需要O ( n ) O(n)O(n)的时间遍历每个结点最多一次。

  • 空间复杂度:O ( n ) O(n)O(n),其中n nn是结点数。入度数组和递归调用栈需要O ( n ) O(n)O(n)的空间。

解法三

预备知识

该解法涉及到并查集。

并查集是一种树型的数据结构,用于处理不相交集合的合并与查询问题。

思路和算法

当每个结点的入度都不超过1 11时,根结点所在的连通分量中一定不存在环,且该连通分量一定是有效的二叉树,简单说明如下:对于除了根结点以外的每个结点v vv,一定存在恰好一条指向结点v vv的有向边,将这条有向边的起点记为结点u uu,则结点u uu是结点v vv的父结点,每一对相邻结点之间的父结点和子结点关系形成二叉树。

因此,使用并查集时不需要考虑每条边的方向,只要将每条边连接的两个结点合并即可。

并查集初始化时,n nn个结点分别属于n nn个不同的集合,每个集合只包含一个结点,集合个数等于结点个数。

初始化之后,遍历每条边,将同一条边连接的两个结点所在的集合做合并,每次合并之后将集合个数减1 11

遍历结束之后,并查集的集合个数即为连通分量数,根据并查集的集合个数是否等于1 11判断有向图是否连通。

代码

classSolution{intn;int[]leftChild;int[]rightChild;intvisitCount=0;publicbooleanvalidateBinaryTreeNodes(intn,int[]leftChild,int[]rightChild){this.n=n;this.leftChild=leftChild;this.rightChild=rightChild;intedges=0;int[]indegrees=newint[n];for(inti=0;i<n;i++){intleft=leftChild[i],right=rightChild[i];if(left>=0){edges++;indegrees[left]++;}if(right>=0){edges++;indegrees[right]++;}}if(edges!=n-1){returnfalse;}introot=-1;for(inti=0;i<n;i++){if(indegrees[i]==0){if(root<0){root=i;}else{returnfalse;}}elseif(indegrees[i]>1){returnfalse;}}if(root<0){returnfalse;}UnionFinduf=newUnionFind(n);for(inti=0;i<n;i++){intleft=leftChild[i],right=rightChild[i];if(left>=0){uf.union(i,left);}if(right>=0){uf.union(i,right);}}returnuf.getCount()==1;}}classUnionFind{privateint[]parent;privateint[]rank;privateintcount;publicUnionFind(intn){parent=newint[n];for(inti=0;i<n;i++){parent[i]=i;}rank=newint[n];count=n;}publicvoidunion(intx,inty){introotx=find(x);introoty=find(y);if(rootx!=rooty){if(rank[rootx]>rank[rooty]){parent[rooty]=rootx;}elseif(rank[rootx]<rank[rooty]){parent[rootx]=rooty;}else{parent[rooty]=rootx;rank[rootx]++;}count--;}}publicintfind(intx){if(parent[x]!=x){parent[x]=find(parent[x]);}returnparent[x];}publicintgetCount(){returncount;}}

复杂度分析

  • 时间复杂度:O ( n × α ( n ) ) O(n \times \alpha(n))O(n×α(n)),其中n nn是结点数,α \alphaα是反阿克曼函数。并查集的初始化需要O ( n ) O(n)O(n)的时间,然后遍历n − 1 n - 1n1条边执行n − 1 n - 1n1次合并操作,这里的并查集使用了路径压缩和按秩合并,单次操作的时间复杂度是O ( α ( n ) ) O(\alpha(n))O(α(n)),因此并查集初始化之后的操作的时间复杂度是O ( n × α ( n ) ) O(n \times \alpha(n))O(n×α(n)),总时间复杂度是O ( n × α ( n ) ) O(n \times \alpha(n))O(n×α(n))

  • 空间复杂度:O ( n ) O(n)O(n),其中n nn是结点数。并查集需要O ( n ) O(n)O(n)的空间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/16 4:48:23

【51单片机倒计时清翔的板子2片573驱动数码管】2023-10-28

缘由51单片机模拟定时炸弹_编程语言-CSDN问答 用矩阵键盘在数码管上输入数字作为炸弹的倒计时&#xff0c;独立键盘控制倒计时开始&#xff0c;暂停&#xff0c;提前引爆键&#xff0c;倒计时最后三秒蜂鸣器随倒计时响&#xff0c;求源码。 以下代码演示相关功能实现。 #inc…

作者头像 李华
网站建设 2026/5/16 4:47:39

2026届毕业生推荐的AI科研平台解析与推荐

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 可面向在校学生的专业论文 AI 网站&#xff0c;能给科研人员提供高效学术辅助支持&#xff0…

作者头像 李华
网站建设 2026/5/16 4:47:09

TexLab定义与引用系统:如何实现精确的跳转和查找功能

TexLab定义与引用系统&#xff1a;如何实现精确的跳转和查找功能 【免费下载链接】texlab An implementation of the Language Server Protocol for LaTeX 项目地址: https://gitcode.com/gh_mirrors/te/texlab TexLab作为一款强大的LaTeX语言服务器&#xff0c;其定义与…

作者头像 李华
网站建设 2026/5/16 4:46:41

DevUI最佳实践:企业级Angular应用开发的完整解决方案

DevUI最佳实践&#xff1a;企业级Angular应用开发的完整解决方案 【免费下载链接】ng-devui Angular UI Component Library based on DevUI Design 项目地址: https://gitcode.com/DevCloudFE/ng-devui DevUI是基于DevUI Design设计体系的Angular UI组件库&#xff0c;为…

作者头像 李华
网站建设 2026/5/16 4:46:22

互联网大厂Java求职面试:微服务与云原生的挑战与应对

互联网大厂Java求职面试&#xff1a;微服务与云原生的挑战与应对 在一次互联网大厂的Java面试中&#xff0c;面试官和候选人燕双非之间展开了一场精彩的技术讨论&#xff0c;涉及到微服务与云原生的多个方面。下面是他们的对话。第一轮提问 面试官&#xff1a; 燕双非&#xff…

作者头像 李华