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

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

    1. 1
    2. / \
    3. 2 3
    4. /
    5. 4

    输出:false

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

    1. 1
    2. / \
    3. 2 3
    4. \ \
    5. 4 5

    输出:true

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

    1. 1
    2. / \
    3. 2 3
    4. \
    5. 4

    输出:false

    根据题意,应当先分别计算出两个节点的深度以及父节点,若深度不同,则不是堂兄弟节点;若深度相同,则判断父节点是否相同,若相同,则不是堂兄弟节点,反之是堂兄弟节点。

    熟悉的二叉树的深度算法:

    1. public int treeDept(TreeNode root) {
    2. if(root == null) {
    3. return 0;
    4. }
    5. return Math.max(treeDept(root.left), treeDept(root.right)) + 1;
    6. }

    从二叉树的深度算法中可以推导出计算某个节点的深度算法:

    1. int target;
    2. int targetDept = -1;
    3. public int targetNodeDept(TreeNode root, int target) {
    4. this.target = target;
    5. nodeDept(root, 0);
    6. return targetDept;
    7. }
    8. public void nodeDept(TreeNode node, int dept) {
    9. if (node == null) {
    10. return;
    11. }
    12. if (node.val == target) {
    13. targetDept = dept + 1;
    14. }
    15. nodeDept1(node.left, dept + 1);
    16. nodeDept1(node.right, dept + 1);
    17. }

    第一版算法,先得到两个目标节点的深度:

    1. int xNodeVal;
    2. int yNodeVal;
    3. int xNodeDept;
    4. int yNodeDept;
    5. public boolean isCousins(TreeNode root, int x, int y) {
    6. this.xNodeVal = x;
    7. this.yNodeVal = y;
    8. nodeDept(root, 0);
    9. }
    10. private void nodeDept(TreeNode root, int dept) {
    11. if (root == null) {
    12. return;
    13. }
    14. if (root.val == xNodeVal) {
    15. xNodeDept = dept;
    16. }
    17. if (root.val == yNodeVal) {
    18. yNodeDept = dept;
    19. }
    20. dept(root.left, dept + 1);
    21. dept(root.right, dept + 1);
    22. }

    �同理,若想得到节点的父节点,可参考节点深度算法,扩充一个父节点参数:

    1. int xNodeVal;
    2. int yNodeVal;
    3. int xNodeDept;
    4. int yNodeDept;
    5. TreeNode xNodeParent;
    6. TreeNode yNodeParent;
    7. public boolean isCousins(TreeNode root, int x, int y) {
    8. this.xNodeVal = x;
    9. this.yNodeVal = y;
    10. nodeDept(root, 0, null);
    11. }
    12. private void nodeDept(TreeNode root, int dept, TreeNode parentNode) {
    13. if (root == null) {
    14. return;
    15. }
    16. if (root.val == xNodeVal) {
    17. xNodeDept = dept;
    18. xNodeParent = parentNode;
    19. }
    20. if (root.val == yNodeVal) {
    21. yNodeDept = dept;
    22. yNodeParent = parentNode;
    23. }
    24. dept(root.left, dept + 1, root);
    25. dept(root.right, dept + 1, root);
    26. }

    完整的算法:

    1. int xNodeVal;
    2. int yNodeVal;
    3. int xNodeDept;
    4. int yNodeDept;
    5. TreeNode xNodeParent;
    6. TreeNode yNodeParent;
    7. public boolean isCousins(TreeNode root, int x, int y) {
    8. this.xNodeVal = x;
    9. this.yNodeVal = y;
    10. nodeDept(root, 0, null);
    11. return xNodeDept == yNodeDept && xNodeParent != yNodeParent;
    12. }
    13. private void nodeDept(TreeNode root, int dept, TreeNode parentNode) {
    14. if (root == null) {
    15. return;
    16. }
    17. if (root.val == xNodeVal) {
    18. xNodeDept = dept;
    19. xNodeParent = parentNode;
    20. }
    21. if (root.val == yNodeVal) {
    22. yNodeDept = dept;
    23. yNodeParent = parentNode;
    24. }
    25. dept(root.left, dept + 1, root);
    26. dept(root.right, dept + 1, root);
    27. }