来源

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-complete-tree-nodes/

描述

给出一个完全二叉树,求出该树的节点个数。

说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 222. 完全二叉树的节点个数(Count Complete Tree Nodes) - 图1个节点。

示例:
输入:
1
/ \
2 3
/ \ /
4 5 6

输出: 6

题解

递归版

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. class Solution {
  11. public int countNodes(TreeNode root) {
  12. if (root == null) {
  13. return 0;
  14. }
  15. return 1 + countNodes(root.left) + countNodes(root.right);
  16. }
  17. }

复杂度分析

  • 时间复杂度:222. 完全二叉树的节点个数(Count Complete Tree Nodes) - 图2
  • 空间复杂度:222. 完全二叉树的节点个数(Count Complete Tree Nodes) - 图3=222. 完全二叉树的节点个数(Count Complete Tree Nodes) - 图4,其中d指的是树的的高度,运行过程中堆栈所使用的空间。

迭代版

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. class Solution {
  11. public int computeDepth(TreeNode node) {
  12. int d = 0;
  13. while (node.left != null) {
  14. node = node.left;
  15. ++d;
  16. }
  17. return d;
  18. }
  19. public boolean exists(int idx, int d, TreeNode node) {
  20. int left = 0, right = (int) Math.pow(2, d) - 1;
  21. int pivot;
  22. for (int i = 0; i < d; i++) {
  23. pivot = left + (right - left) / 2;
  24. if (idx <= pivot) {
  25. node = node.left;
  26. right = pivot;
  27. } else {
  28. node = node.right;
  29. left = pivot + 1;
  30. }
  31. }
  32. return node != null;
  33. }
  34. public int countNodes(TreeNode root) {
  35. if (null == root) {
  36. return 0;
  37. }
  38. int d = computeDepth(root);
  39. if (0 == d) {
  40. return 1;
  41. }
  42. int left = 1, right = (int)Math.pow(2, d) - 1;
  43. int pivot;
  44. while (left <= right) {
  45. pivot = left + (right - left) / 2;
  46. if (exists(pivot, d, root)) {
  47. left = pivot + 1;
  48. } else {
  49. right = pivot - 1;
  50. }
  51. }
  52. return (int)Math.pow(2, d) - 1 + left;
  53. }
  54. }

复杂度分析

  • 时间复杂度:222. 完全二叉树的节点个数(Count Complete Tree Nodes) - 图5=222. 完全二叉树的节点个数(Count Complete Tree Nodes) - 图6,其中d是树的高度;
  • 空间复杂度:222. 完全二叉树的节点个数(Count Complete Tree Nodes) - 图7