大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。
这期给大家出一篇二叉树算法题,如何利用满二叉树的特性计算完全二叉树的节点数,对于满二叉树和完全二叉树还不熟悉的读者可以看看我之前写过的一文读懂二叉树去了解下。
满二叉树的左右节点深度一定是相等的,完全二叉树的最底层的节点数一定是连续的,所以利用这个特性,计算完全二叉树的节点数。
进阶之路!!!
遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?
利用满二叉树的特性
满二叉树的节点数:2^n - 1 (2的n次方 - 1)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
// 力扣的#222号题目
class Solution {
public int countNodes(TreeNode root) {
if(root == null) {
return 0;
}
// 完全二叉树 递归写出来 利用完全二叉树的特性
TreeNode left = root.left;
TreeNode right = root.right;
int leftNum = 0;
int rightNum = 0;
// 计算左右是不是满二叉树,如果是,用满二叉树的特性直接计算:2^n - 1
while(left != null) {
left = left.left;
leftNum++;
}
while(right != null) {
right = right.right;
rightNum++;
}
if(rightNum == leftNum) { // 左右深度相等,是一个满二叉树
// 计算出满二叉树的节点数返回给上面的节点
return (2<<leftNum) - 1; // 这里用的位运算:2 << n == 2的n + 1 次方,这里n是从0开始++的
}
int result = 0;
int le = countNodes(root.left); // 左
int ri = countNodes(root.right); // 右
result = le + ri + 1; // 中
return result;
}
}
广度优先搜索的层序遍历方法
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
if(root == null) {
return 0;
}
// 层序遍历试一试
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int tem = 0;
while(!queue.isEmpty()) {
int size = queue.size();
tem = tem + size;
while(size-- > 0) {
TreeNode node = queue.poll();
if(node.left != null) {
queue.offer(node.left);
}
if(node.right != null) {
queue.offer(node.right);
}
}
}
return tem;
}
}
后序遍历的递归(没有利用满二叉树的特性的普通递归)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
if(root == null) {
return 0;
}
// 递归
int result = 0;
int left = countNodes(root.left); // 左
int right = countNodes(root.right); // 右
result = left + right + 1; // 中
return result;
}
}
最后
一定要理解,知其然知其所以然!!!