LeetCode——993. 二叉树的堂兄弟节点(Java)

题目描述

题干:
在二叉树中,根节点位于深度 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了

当然还有其他更优的思路,但都是在经典思路的基础上减少多余的计算,算是剪枝吧

如果文章存在问题或者有更好的题解,欢迎在评论区斧正和评论,各自努力,你我最高处见!
posted @ 2021-05-17 15:58  21岁还不是架构师  阅读(69)  评论(0编辑  收藏  举报