返回

前端面试算法题解析——完全二叉树的节点个数

前端

对于前端工程师来说,掌握算法知识是提升竞争力的关键。在本次文章中,我们将共同探索一道经典的前端面试算法题——完全二叉树的节点个数。通过对这道题目的深入剖析,不仅可以锻炼我们的算法思维,更能为面试做好充分准备。

一、题目

给定一棵完全二叉树的根节点 root,求出该树的节点个数。完全二叉树的定义如下:

* 完全二叉树的左子树和右子树高度相等。
* 完全二叉树的每一层都填满了节点。

二、思路解析

计算完全二叉树的节点个数,可以通过层序遍历的方式。层序遍历从根节点开始,逐层遍历所有节点,直到遍历完最后一层。每遍历一层,节点个数加一。

三、代码实现

```typescript
/**
 * 计算完全二叉树的节点个数
 *
 * @param root 完全二叉树的根节点
 * @returns 节点个数
 */
const countNodes = (root: TreeNode | null): number => {
  if (!root) {
    return 0;
  }

  let level = 0;
  let cur = root;

  // 计算树的高度
  while (cur.left) {
    level++;
    cur = cur.left;
  }

  // 使用二分查找法计算节点个数
  let low = 1 << level;
  let high = (1 << (level + 1)) - 1;

  while (low < high) {
    const mid = Math.floor((low + high) / 2);
    if (exist(root, level, mid)) {
      low = mid + 1;
    } else {
      high = mid;
    }
  }

  return low - 1;
};

/**
 * 判断完全二叉树中是否存在指定节点
 *
 * @param root 完全二叉树的根节点
 * @param level 节点所在层级
 * @param index 节点索引(从左到右)
 * @returns 是否存在
 */
const exist = (root: TreeNode | null, level: number, index: number): boolean => {
  if (!root) {
    return false;
  }

  // 从左到右依次检查每个节点是否存在
  let cur = root;
  for (let i = 0; i < level; i++) {
    const bit = 1 << i;
    if (index & bit) {
      cur = cur.right;
    } else {
      cur = cur.left;
    }
  }

  return cur !== null;
};

四、复杂度分析

  • 时间复杂度:O(logN)。其中 N 是完全二叉树的节点个数。
  • 空间复杂度:O(1)。

五、总结

通过本文的讲解,我们深入理解了计算完全二叉树节点个数的算法原理和代码实现。掌握这道算法题不仅可以提升我们的面试竞争力,更能锻炼我们的算法思维,为解决其他复杂算法问题奠定坚实的基础。