日新刷题 - 993. 二叉树的堂兄弟节点

36 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情

一、题目描述:

993. 二叉树的堂兄弟节点 - 力扣(LeetCode)

在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。

如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。

我们给出了具有唯一值的二叉树的根节点 root ,以及树中两个不同节点的值 x 和 y 。

只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。

 

示例 1:

image.png

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

示例 2:

image.png

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

示例 3:

image.png

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

提示:

  • 二叉树的节点数介于 2 到 100 之间。
  • 每个节点的值都是唯一的、范围为 1 到 100 的整数。  

二、思路分析:

  • 是否为堂兄弟结点, 重点是比较, 1、层级是否相同, 2、父结点的值是否不同
  • 根据上述思路, 将x和y分别作为属性存储在一个对象record中, x和y都有两个属性, 一个是记录结点的层级depth, 还有一个是记录结点的双亲结点的值parent
  • 根结点没有父节点, 值为null
  • 执行广度优先搜索的层级遍历, 当遍历到的结点的值与x或y相符时, 更新record
  • 遍历结束时, 比较1、层级是否相同, 2、父结点的值是否不同

三、AC 代码:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} x
 * @param {number} y
 * @return {boolean}
 */
var isCousins = function(root, x, y) {
    // 队列中数组形式存储结点、双亲节点
    const queue = [[root, null]];
    // 将x和y分别作为属性存储在一个对象record中, x和y都有两个属性, 一个是记录结点的层级depth, 还有一个是记录结点的双亲结点的值parent
    const record = {
        x: {
            depth: undefined,
            parent: undefined,
        },
        y: {
            depth: undefined,
            parent: undefined,
        }
    }
    // 记录当前遍历到哪一层了
    let depth = 0;
    // 层序遍历
    while(queue.length) {
        const length = queue.length;
        depth++;
        for(let i = 0; i < length; i++) {
            const [cur, parent] = queue.shift();
            // 当遍历到的结点的值与x相符时, 更新record
            if(cur.val === x) {
                record.x.depth = depth;
                record.x.parent = parent;
            };
            // 当遍历到的结点的值与y相符时, 更新record
            if(cur.val === y) {
                record.y.depth = depth;
                record.y.parent = parent;
            }
            // 将[结点的左子树, 结点的值]推入队列, 结点的值也是左子结点的父
            if(cur.left) {
                queue.push([cur.left, cur.val]);
            };
            // 将[结点的右子树, 结点的值]推入队列, 结点的值也是右子结点的父
            if(cur.right) {
                queue.push([cur.right, cur.val]);
            }
        }
    }
    // 比较1、层级是否相同, 2、父结点的值是否不同
    if(record.x.depth === record.y.depth && record.x.parent !== record.y.parent ) {
        return true;
    } else {
        return false;
    }
};