题目描述
这是 LeetCode 上的 993. 二叉树的堂兄弟节点 ,难度为 简单。
在二叉树中,根节点位于深度 $0$ 处,每个深度为 $k$ 的节点的子节点位于深度 $k+1$ 处。
如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。
我们给出了具有唯一值的二叉树的根节点 $root$ ,以及树中两个不同节点的值 $x$ 和 $y$ 。
只有与值 $x$ 和 $y$ 对应的节点是堂兄弟节点时,才返回 $true$ 。否则,返回 $false$。
示例 1:

| 输入:root = [1,2,3,4], x = 4, y = 3
输出:false
|
示例 2:

| 输入:root = [1,2,3,null,4,null,5], x = 5, y = 4
输出:true
|
示例 3:

| 输入:root = [1,2,3,null,4], x = 2, y = 3
输出:false
|
提示:
- 二叉树的节点数介于 $2$ 到 $100$ 之间。
- 每个节点的值都是唯一的、范围为 $1$ 到 $100$ 的整数。
DFS
显然,我们希望得到某个节点的「父节点」&「所在深度」,不难设计出如下「DFS 函数签名」:
|
int[] dfs(TreeNode root, TreeNode fa, int depth, int t);
|
之后按照遍历的逻辑处理即可。
需要注意的时,我们需要区分出「搜索不到」和「搜索对象为 $root$(没有 $fa$ 父节点)」两种情况。
我们约定使用 $-1$ 代指没有找到目标值 $t$,使用 $0$ 代表找到了目标值 $t$,但其不存在父节点。
代码:
| class Solution { public boolean isCousins(TreeNode root, int x, int y) { int[] xi = dfs(root, null, 0, x); int[] yi = dfs(root, null, 0, y); return xi[1] == yi[1] && xi[0] != yi[0]; } int[] dfs(TreeNode root, TreeNode fa, int depth, int t) { if (root == null) return new int[]{-1, -1}; if (root.val == t) { return new int[]{fa != null ? fa.val : 1, depth}; } int[] l = dfs(root.left, root, depth + 1, t); if (l[0] != -1) return l; return dfs(root.right, root, depth + 1, t); } }
|
- 时间复杂度:$O(n)$
- 空间复杂度:忽略递归开销为 $O(1)$,否则为 $O(n)$
BFS
能使用 DFS
,自然也能使用 BFS
,两者大同小异。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public boolean isCousins(TreeNode root, int x, int y) { int[] xi = bfs(root, x); int[] yi = bfs(root, y); return xi[1] == yi[1] && xi[0] != yi[0]; } int[] bfs(TreeNode root, int t) { Deque<Object[]> d = new ArrayDeque<>(); d.addLast(new Object[]{root, null, 0}); while (!d.isEmpty()) { int size = d.size(); while (size-- > 0) { Object[] poll = d.pollFirst(); TreeNode cur = (TreeNode)poll[0], fa = (TreeNode)poll[1]; int depth = (Integer)poll[2];
if (cur.val == t) return new int[]{fa != null ? fa.val : 0, depth}; if (cur.left != null) d.addLast(new Object[]{cur.left, cur, depth + 1}); if (cur.right != null) d.addLast(new Object[]{cur.right, cur, depth + 1}); } } return new int[]{-1, -1}; } }
|
- 时间复杂度:$O(n)$
- 空间复杂度:$O(n)$
最后
这是我们「刷穿 LeetCode」系列文章的第 No.993
篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。