[JavaScript 刷题] 树 - 完全二叉树的节点个数, leetcode 222

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JavaScript 刷题] 树 - 完全二叉树的节点个数, leetcode 222相关的知识,希望对你有一定的参考价值。

[javascript 刷题] 树 - 完全二叉树的节点个数, leetcode 222

github repo 地址: https://github.com/GoldenaArcher/js_leetcode,Github 的目录 大概 会更新的更勤快一些。

题目地址:222. Count Complete Tree Nodes

题目

如下:

Given the root of a complete binary tree, return the number of the nodes in the tree.

According to Wikipedia, every level, except possibly the last, is completely filled in a complete binary tree, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.

Design an algorithm that runs in less than O(n) time complexity.

解题思路

这题的暴力解就是扫描所有的结点,每扫描一个节点 count++,那这样的时间复杂度肯定是 O ( n ) O(n) O(n),儿题目的要求是设计一个算法,并且其时间复杂度小于 O ( n ) O(n) O(n)

换言之,暴力地扫面所有结点地做法是无法满足的——不过的确可以通过就是了。

满足题目需求的一种做法就是利用完全二叉树的特点:

  • 完全二叉树除了最后一层外,所有地结点都会被完全填满

换言之,只需要搜索完全二叉树地最后一层即可。

实际操作地做法为:

  1. 查看当前左右子树的高度

  2. 如果左子树高度大于右子树,搜索左子树

    反之搜索右子树

这样在不断遍历地过程中,找到最后一层的最右侧结点。

以这棵树为例:

第一次搜索时,左右子树的高度相同,则代表左子树必然是个完全二叉树,因此无需继续搜索,只需搜索右子树即可。左子树的高度为 2 h 2^h 2h h h h 为左子树的高度。完全二叉树的高度为 2 h − 1 2^h - 1 2h1,这里加上了根节点,就成为了 2 h 2^h 2h

这时候可以继续重复该过程,以此类推。

时间复杂度为 O ( l o g 2 ( n ) ) O(log^2(n)) O(log2(n)),理解方式为:

树的高度 x 树的最后一层子结点数量,即 l o g ( n ) × l o g ( n ) log(n) \\times log(n) log(n)×log(n),总体的时间复杂度还是少于 O ( n ) O(n) O(n) 的:

绿色的是 O ( n ) O(n) O(n) 的时间复杂度,红色的为 O ( l o g 2 ( n ) ) O(log^2(n)) O(log2(n)),蓝色的为 O ( l o g ( n ) ) O(log(n)) O(log(n)),可以看出,这个算法的耗时还是远远低于 O ( n ) O(n) O(n)

另一种理解方法也可以理解成——二叉搜索的二叉搜索。

使用 JavaScript 解题

var countNodes = function (root) 
  if (!root) return 0;

  const height = (root) => 
    let counter = 0;

    while (root) 
      counter++;
      root = root.left;
    

    return counter;
  ;

  const left = height(root.left);
  const right = height(root.right);

  if (left === right) return 2 ** left + countNodes(root.right);

  return 2 ** right + countNodes(root.left);
;

以上是关于[JavaScript 刷题] 树 - 完全二叉树的节点个数, leetcode 222的主要内容,如果未能解决你的问题,请参考以下文章

[JavaScript 刷题] 树 - 从前序与中序遍历序列构造二叉树, leetcode 105

[JavaScript 刷题] 树 - 二叉树的序列化与反序列化, leetcode 297

[JavaScript 刷题] 树 - 二叉树的序列化与反序列化, leetcode 297

整理||深度学习二叉树最强盘点!

整理 || 数据结构二叉树最强盘点!

二叉树面试题刷题模板(终极版)