← 返回题目列表

二叉树中如何判断两个节点是不是堂兄弟节点?

中等 第 28 / 30 题 更新于 2026/07/30
二叉树堂兄弟节点BFS父节点

简化版

堂兄弟节点要求两个节点深度相同,但父节点不同。可以 BFS 按层遍历,在同一层记录目标节点的父节点;如果两个目标都在这一层且父节点不同,就是堂兄弟。

详细版

判断堂兄弟要同时看 depth 和 parent。

常用 BFS:

  • 队列里存 (node, parent)
  • 每次处理一整层。
  • 在当前层查找 x 和 y 的父节点。
  • 如果当前层只找到一个,说明深度不同,返回 false。
  • 如果两个都找到,比较父节点是否不同。

DFS 也可以,记录每个目标的深度和父节点。BFS 的优势是层级语义更直观,找到后可以提前结束。

完整版教学

一、堂兄弟节点的定义是什么

两个节点是堂兄弟,需要满足两个条件:深度相同,父节点不同。只满足一个不够。

    1
   / \
  2   3
 /     \
4       5

4 和 5 深度相同,父节点分别是 2 和 3,所以是堂兄弟。2 和 3 深度相同,但它们是兄弟,不是堂兄弟,因为父节点相同。

二、为什么 BFS 很自然

BFS 一层一层遍历,天然能判断两个节点是否出现在同一深度。每处理一层,只在这一层查找目标。

第 0 层:1
第 1 层:2,3
第 2 层:4,5

如果 x 在第 1 层,y 在第 2 层,那么处理第 1 层时只找到 x,就可以知道它们不是堂兄弟。

三、为什么必须记录父节点

同一层的两个节点可能是兄弟,也可能是堂兄弟。只看层数无法区分。

队列元素可以存:

(node, parent)

当遇到 x 或 y 时,把 parent 记录下来。当前层结束后,如果两个 parent 都存在,就比较是否为同一个对象。

四、按层处理为什么比逐个处理安全

如果 BFS 不按层分组,遇到第一个目标就急着判断,可能还没扫描完同层的另一个目标。正确做法是每轮固定当前队列长度,处理完这一整层再做判断。

for (let i = 0; i < levelSize; i++) {
  // 只处理当前层节点
}

levelSize 是层级边界。它让“同一深度”在代码里有明确范围。

五、DFS 怎么做

DFS 可以记录 x 和 y 的 (depth,parent)。遍历整棵树后比较:

x.depth == y.depth && x.parent != y.parent

DFS 写法也很简单,但需要小心父节点传参。BFS 更贴合“同层”的定义,通常更容易讲清。

六、边界和复杂度

如果树为空、只找到一个目标、两个目标值不存在,都不是堂兄弟。时间复杂度 O(n),空间复杂度 BFS 最坏 O(w),w 是最大宽度;DFS 递归栈 O(h)。

条件是否堂兄弟原因
深度相同、父节点不同满足定义
深度相同、父节点相同这是兄弟节点
深度不同不在同一层
只找到一个目标另一个节点不存在或值不匹配

记忆钩子:堂兄弟不是“同层就行”,还要“不是同一个父亲”。

七、常见误区与追问

  • 误区:同一层的节点一定是堂兄弟。 同一父节点的兄弟不是堂兄弟。
  • 误区:找到一个目标就能立刻返回。 需要处理完整层,确认另一个目标是否也在同层。
  • 误区:比较父节点值就够。 更稳的是比较父节点对象;值可能重复。
  • 追问:DFS 能做吗? 能,记录两个目标的深度和父节点后比较。
  • 追问:复杂度是多少? 时间 O(n),BFS 空间最坏 O(w),DFS 栈空间 O(h)。

八、加强记忆

判断堂兄弟只需要两个信息:深度和父节点。BFS 按层天然拿深度,队列里带 parent 就能判断父节点是否不同。记住“同层不同父”,就不会把兄弟节点误判成堂兄弟。