[LeetCode打卡24-02-08]p933.二叉树的堂兄弟节点

77 阅读3分钟

题目摘要

题目链接

题目链接:933.二叉树的堂兄弟节点

题目截图

题目模板

class Solution {
    public boolean isCousins(TreeNode root, int x, int y) {

    }
}

解题思路

首先阅读题目,这里我直接把题目中的关键信息做了加粗处理

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

第一眼看到这个题目,Easy难度的题,感觉比较简单,直接用最笨的方法来写就好了,先把关键信息摘要出来:

  1. 题目给的是一棵二叉树
  2. 符合条件的两个节点要求深度相同但父节点不同
  3. 模板中方法返回值为一个布尔值,仅需要判断两个节点是否为符合条件的节点

树的遍历

既然是要在树中搜索两个节点,那树的遍历肯定是逃不开

对于树的遍历一般有三种:先序遍历、中序遍历、后续遍历。对于这道题我的主观感觉上三种遍历形式没有什么不同,所以就随机采取了中序遍历这种方式,毕竟代码写起来建店,下面是代码:

class Solution {
    public boolean isCousins(TreeNode root, int x, int y) {
        traversingTree(root);
        return false;
    }

    private void traversingTree(TreeNode root) {
        if (Objects.isNull(root)) {
            return;
        }
        System.out.println(root.val);
        traversingTree(root.left);
        traversingTree(root.right); 
    }
}

值的传递

结果的两个节点需要符合的条件:

  • 深度相同
  • 父节点不同

既然要判断这两个值,那我们在遍历树的过程中,肯定要先能取到这两个值以及这两个节点。这里也没有什么高深莫测的方法,直接进行简单透传即可,下面是代码:

class Solution {
    public boolean isCousins(TreeNode root, int x, int y) {
        traversingTree(root, x, y, 0, -1);
        return false;
    }

    private void traversingTree(TreeNode root, int x, int y, int layer, int parent) {
        if (Objects.isNull(root)) {
            return;
        }
        System.out.println(root.val);
        traversingTree(root.left, x, y, layer + 1, root.val);
        traversingTree(root.right, x, y, layer + 1, root.val); 
    }
}

结果记录

由于要记录两个节点的深度、父节点两个信息,所以这里我直接新建了一个对象来保存信息:

class Solution {
    public boolean isCousins(TreeNode root, int x, int y) {
        traversingTree(root, x, y, 0, -1, new Result());
        return false;
    }

    private void traversingTree(TreeNode root, int x, int y, int layer, int parent, Result res) {
        if (Objects.isNull(root)) {
            return;
        }
        System.out.println(root.val);
        traversingTree(root.left, x, y, layer + 1, root.val, res);
        traversingTree(root.right, x, y, layer + 1, root.val, res); 
    }

    private class Result {
      int layer = -1;
      int parent = -1;
    }
}

这里留个疑问点,为什么不直接用两个int变量透传下去?

条件判断

万事俱备只欠东风,不多说,直接给出最终的代码:

class Solution {
    public boolean isCousins(TreeNode root, int x, int y) {
        return traversingTree(root, x, y, 0, -1, new Result());
    }

    private boolean traversingTree(TreeNode root, int x, int y, int layer, int parent, Result res) {
        if (Objects.isNull(root)) {
            return false;
        }
        if (x == root.val || y == root.val) {
            if (res.layer == -1 || res.parent == -1) {
                res.layer = layer;
                res.parent = parent;
            } else if (res.parent != parent && res.layer == layer) {
                return true;
            }
        }
        return traversingTree(root.left, x, y, layer + 1, root.val, res)
                || traversingTree(root.right, x, y, layer + 1, root.val, res);
    }

    private class Result {
        int layer = -1;
        int parent = -1;
    }
}

这里主要有几个改动点:

  1. 遍历方法返回值改成了boolean,方便遍历过程中做判断,也方便直接调用返回结果
  2. 如果根节点为null,则直接返回false,防止出现NPE以及遍历中断的情况
  3. 因为题目中没有给出x和y的左右关系,所以直接使用x == root.val || y == root.val的条件来判断是否符合条件,也就忽略了x和y的先后关系
  4. 当res的两个值为-1时,认为是初始化状态,当第一次命中节点时,先赋值,第二次命中节点时再判断

结果展示