[路飞]_993. 二叉树的堂兄弟节点

1,281 阅读2分钟

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战

993. 二叉树的堂兄弟节点

题目

在二叉树中,根节点位于深度 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

题解

直观DFS

  • 深度优先遍历二叉树,通过变量 xLevelyLevelxLevel、yLevel记录节点 x,y x ,y 的层级
  • 又因为题目定义堂兄弟节点为:二叉树的两个节点深度相同,但父节点不同,所以需要通过变量 signsign 维护两个节点是否时同一个父节点
  • 节点判断x,y x ,y 是否为自身自节点,这个逻辑通过代码表示也挺长的所以代码写起来就比较丑

根据题目表述思路编辑代码如下:

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
  }
}