持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情
一、题目描述:
在二叉树中,根节点位于深度 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
提示:
- 二叉树的节点数介于 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;
}
};