题目描述
题干:
在二叉树中,根节点位于深度 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
题解思路
判断是否为堂兄弟节点,堂兄弟是指不是相同父亲节点但高度相同的节点
这里首先采用的广度优先遍历,高度作为关键条件可以比深度优先的代码更优雅
但是两种方式都是在经典写法中添加标志比较判断,这里只给出BFS写法,DFS大同小异
正确代码
public class MyIsCousins {
//定义两个元素的标志
int x;
TreeNode xParent;
int xDepth;
boolean xFound;
int y;
TreeNode yParent;
int yDepth;
boolean yFound;
//BFS
public boolean isCousins(TreeNode root, int x, int y) {
this.x = x;
this.y = y;
//定义和初始化广度优先和记录高度的的队列
Queue<TreeNode> nodeQueue = new LinkedList<>();
Queue<Integer> depthQueue = new LinkedList<>();
depthQueue.offer(0);
nodeQueue.offer(root);
judge(root, null, 0);
//经典bfs
while (!nodeQueue.isEmpty()) {
TreeNode node = nodeQueue.poll();
int depth = depthQueue.poll();
if (node.left != null) {
nodeQueue.offer(node.left);
depthQueue.offer(depth + 1);
judge(node.left, node, depth + 1);
}
if (node.right != null) {
nodeQueue.offer(node.right);
depthQueue.offer(depth + 1);
judge(node.right, node, depth + 1);
}
//提前判断是否结束循环
if (xFound && yFound) {
break;
}
}
//堂兄弟为高度相同但是父节点不同
return xDepth == yDepth && yParent != xParent;
}
//判断是否遍历过x和y
public void judge(TreeNode node, TreeNode parent, int depth) {
if (node.val == x) {
xParent = parent;
xDepth = depth;
xFound = true;
} else if (node.val == y) {
yParent = parent;
yDepth = depth;
yFound = true;
}
}
}
结论
其实除了特殊的题型,大部分的树问题两种方法都可以解决,无非是代码细节部分
当然这里并不是最优解,因为其实找到第一个元素的时候,如果当前层中没有另外一个元素其实就可以break了
当然还有其他更优的思路,但都是在经典思路的基础上减少多余的计算,算是剪枝吧
如果文章存在问题或者有更好的题解,欢迎在评论区斧正和评论,各自努力,你我最高处见!