「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」
题目
在二叉树中,根节点位于深度 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
题解
直观DFS
- 深度优先遍历二叉树,通过变量 记录节点 的层级
- 又因为题目定义堂兄弟节点为:二叉树的两个节点深度相同,但父节点不同,所以需要通过变量 维护两个节点是否时同一个父节点
- 节点判断 是否为自身自节点,这个逻辑通过代码表示也挺长的所以代码写起来就比较丑
根据题目表述思路编辑代码如下:
var isCousins = function (root, x, y) {
let xLevel = -1
let yLevel = -1
let sign = 1
dfs(root, 0)
//console.log('xLevel',xLevel,yLevel)
if (sign) {
return xLevel === yLevel
} else {
return false
}
function dfs(node, level) {
if (node === null) return
if (node.val === x) xLevel = level
if (node.val === y) yLevel = level
if (
node &&
node.left &&
node.left.val === x &&
node &&
node.right &&
node.right.val === y
) {
sign = 0
return
}
if (
node &&
node.left &&
node.left.val === y &&
node &&
node.right &&
node.right.val === x
) {
sign = 0
return
}
dfs(node.left, level + 1)
dfs(node.right, level + 1)
}
}
上述代码虽然思路比较直观,但是太长了,程序员应该将自己代码简化一下;
优化后代码:
var isCousins = function (root, x, y) {
let xLevel = -1
let yLevel = -1
let xParent = null
let yParent = null
dfs(root, 0, null)
return xLevel === yLevel && xParent !== yParent
function dfs(node, level, parent) {
if (node === null) return
if (node.val === x) {
xLevel = level
xParent = parent
}
if (node.val === y) {
yLevel = level
yParent = parent
}
dfs(node.left, level + 1, node)
dfs(node.right, level + 1, node)
}
}
优化后代码依旧有了四个额外变量保存数据,这点看着还是有点别扭,能在优化吗?
可以,在递归的时候处理层级同一父节点关系,直接返回
var isCousins = function (root, x, y) {
return dfs(root, 0) === -1
function dfs(node, level) {
if (!node) return 0
if (node.val == x || node.val == y) return level
const l = dfs(node.left, level + 1)
const r = dfs(node.right, level + 1)
if (l < 0) return l
if (r < 0) return r
if (l > 0 && r > 0) {
if (l == r && l != level + 1) return -1
else return -2
}
if (l > 0) return l
if (r > 0) return r
return 0
}
}