首页 > 其他分享 >LeetCode222.完全二叉树的节点个数

LeetCode222.完全二叉树的节点个数

时间:2024-07-28 11:19:34浏览次数:10  
标签:count 遍历 cur LeetCode222 个数 二叉树 root 节点

题目链接:https://leetcode.cn/problems/count-complete-tree-nodes/description/

题目叙述

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

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

示例 1:


输入:root = [1,2,3,4,5,6]
输出:6

示例 2:

输入:root = []
输出:0

示例 3:

输入:root = [1]
输出:1

提示:

树中节点的数目范围是[0, 5 * 10 ^4]

0 <= Node.val <= 5 * 10^4

题目数据保证输入的树是 完全二叉树

思路

这题可以使用递归的方法和迭代的方法,两种都是可以的。并且这道题使用前序,中序,或者后序的遍历顺序都是可以做出来的,这题并没有限制我们的遍历顺序,下面我会讲解递归法和迭代法

递归法

递归要确定的有三个条件

  1. 递归函数的传入参数和返回值,这题明显我们需要传入一个树的根节点root,并且要返回一个int类型的值。
  2. 递归函数的结束条件,这题明显我们遍历到空节点的时候,我们就需要返回了。因此,递归的结束条件为: if (root == NULL) return 0;
  3. 单层递归的逻辑:我们这道题,是要求所有节点的个数,我们可以拆解为左子树的节点个数+右子树的节点个数+根节点(1)。因此,我们可以对这个步骤拆分,对左子树的左右子树做同样的事情,调用同样的
    函数,这就是单层递归的逻辑,对不同的对象使用相同的条件。

通过上面的分析,我们很快就可以得出递归法的代码:

//递归法求完全二叉树的节点个数
class Solution {
public:
	int countNodes(TreeNode* root) {
		//碰到空节点,我们就返回
		if (root == NULL) return 0;
		//递归求左子树的节点个数
		int leftCount = countNodes(root->left);
		//递归求右子树的节点个数
		int rightCount = countNodes(root->right);
		//总节点个数等于左节点个数加右节点的个数
		return leftCount + rightCount + 1;
	}
};

其实,递归法的代码能够非常简结,不过这样就看不出来我们分析的过程了,需要的读者可以自行选择哪一种的代码

//递归法求完全二叉树的节点个数
class Solution {
public:
	int countNodes(TreeNode* root) {
		//碰到空节点,我们就返回
		if (root == NULL) return 0;
		//总节点个数等于左节点个数加右节点的个数
		return countNodes(root->left)+countNodes(root->right) + 1;
	}
};

迭代法

这题使用递归法是最简单的做法,不过其实我们也可以使用迭代法来一个一个数节点的个数,其实递归的本质就是穷举,我们迭代法只不过是将暴力枚举的过程形象表示出来了而已

  1. 迭代法的前序遍历

我们在使用栈来模拟前序遍历时,只需要一个count变量,每一次出栈的时候,代表着有一个节点处理完了,我们让这个count变量自增一次即可

//前序遍历求完全二叉树的节点个数
class Solution {
public:
	int countNodes(TreeNode* root) {
		if (root == NULL) return 0;
		stack<TreeNode*> st;
		st.push(root);
		//设置count变量来计数
		int count = 0;
		while (!st.empty()) {
			TreeNode* cur = st.top();
			st.pop();
			//出栈一次我们就自增一次
			count++;
			//先放右孩子,因为栈是一种后进先出的结构(不过这里先后处理其实无所谓,因为节点个数和遍历顺序无关)
			if (cur->right != NULL) st.push(cur->right);
			if (cur->left != NULL) st.push(cur->left);
		}
		return count;
	}
};
  1. 中序遍历,中序遍历其实和前序遍历差不多是一样的道理,每出栈一次我们就让count自增一次即可
//中序遍历求完全二叉树的节点个数
class Solution {
public:
	int countNodes(TreeNode* root) {
		if (root == NULL) return 0;
		stack<TreeNode*> st;
		TreeNode* cur = root;
		//设置count变量
		int count = 0;
		while (cur != NULL || !st.empty()) {
			if (cur != NULL) {
				st.push(cur);
				cur = cur->left;
			}
			else {
			    cur = st.top();
				st.pop();
				//出栈一次就自增一次
				count++;
				cur = cur->right;
			}
		}
		return count;
	}
};
  1. 层序遍历,这题使用层序遍历也是可以的,只不过就是栈换成了队列,出队一次我们就自增一次count
//层序遍历求完全二叉树的节点个数
class Solution {
public:
	int countNodes(TreeNode* root) {
		if (root == NULL) return 0;
		queue<TreeNode*> que;
		que.push(root);
		//定义count遍历
		int count = 0;
		while (!que.empty()) {
			int size = que.size();
			while (size--) {
				TreeNode* cur = que.front();
				que.pop();
				//出队一次就自增一次
				count++;
				if (cur->left != NULL) que.push(cur->left);
				if (cur->right != NULL) que.push(cur->right);
			}
		}
		return count;
	}
};

标签:count,遍历,cur,LeetCode222,个数,二叉树,root,节点
From: https://www.cnblogs.com/Tomorrowland/p/18327987

相关文章

  • 如何强制某些节点在networkX中具有特定颜色
    我想要为networkx图的节点着色,但我也希望能够强制一组节点为特定颜色,同时仍然能够正确地为图中的所有节点着色。有谁知道如何做到这一点?可以通过将color属性传递给nx.draw函数,以将特定节点强制为特定颜色,同时仍然能够正确地为图形中的所有节点着色。......
  • 数据结构——链式二叉树(C语言版)
    链式二叉树的结构⽤链表来表⽰⼀棵⼆叉树,即⽤链来指⽰元素的逻辑关系。通常的⽅法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别⽤来给出该结点左孩⼦和右孩⼦所在的链结点的存储地址。                                ......
  • (leetcode学习)236. 二叉树的最近公共祖先
    给定一个二叉树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T的两个节点p、q,最近公共祖先表示为一个节点x,满足x是p、q的祖先且x的深度尽可能大(一个节点也可以是它自己的祖先)。”示例1:输入:root=[3,5,1,6,2,0,8,nul......
  • 数据结构-二叉树(顺序结构)
    引言顺序结构存储就是使⽤数组来存储,⼀般只适合表⽰完全⼆叉树,因为不是完全⼆叉树会有空间的浪费,完全⼆叉树更适合使⽤顺序结构存储。一、堆的概念将一个元素集合k里,所有数据按照完成二叉树的顺序存储方式存储。并且数组中的元素,满足以下关系i=0、1、2...,则称为......
  • leetcode105. 从前序与中序遍历序列构造二叉树,步骤详解附代码
    leetcode105.从前序与中序遍历序列构造二叉树给定两个整数数组preorder和inorder,其中preorder是二叉树的先序遍历,inorder是同一棵树的中序遍历,请构造二叉树并返回其根节点。示例1:输入:preorder=[3,9,20,15,7],inorder=[9,3,15,20,7]输出:[3,9,20,nul......
  • 【数据结构】二叉树
    目录二叉树特殊二叉树二叉树的性质二叉树的模拟实现存储结构接口实现内部类遍历前序遍历中序遍历后序遍历遍历确定二叉树层序遍历获取节点个数获取叶子节点的个数获取第K层节点的个数获取二叉树的高度检测值为value的元素是否存在判断一棵树是不是完全二叉树练习链接......
  • ComfyUI插件:ComfyUI Impact 节点(一)
    前言:学习ComfyUI是一场持久战,而ComfyUIImpact是一个庞大的模块节点库,内置许多非常实用且强大的功能节点,例如检测器、细节强化器、预览桥、通配符、Hook、图片发送器、图片接收器等等。通过这些节点的组合运用,我们可以实现的工作有很多,例如自动人脸检测和优化修复、区域增强、......
  • ComfyUI插件:ComfyUI Impact 节点(一)
    前言:学习ComfyUI是一场持久战,而ComfyUIImpact是一个庞大的模块节点库,内置许多非常实用且强大的功能节点,例如检测器、细节强化器、预览桥、通配符、Hook、图片发送器、图片接收器等等。通过这些节点的组合运用,我们可以实现的工作有很多,例如自动人脸检测和优化修复、区域增......
  • ComfyUI进阶:Comfyroll节点 (最终篇)+应用实例
    前言:学习ComfyUI是一场持久战,而Comfyroll是一款功能强大的自定义节点集合,专为ComfyUI用户打造,旨在提供更加丰富和专业的图像生成与编辑工具。借助这些节点,用户可以在静态图像的精细调整和动态动画的复杂构建方面进行深入探索。Comfyroll的节点设计简洁易用,功能强大,是每个希望......
  • 二叉树的遍历
    提纲挈领的说,先序中序后序的遍历区别在于遍历根节点的时机。 1.先序        1.1递归形式 遍历过程为:①访问根结点;②先序遍历其左子树;③先序遍历其右子树。voidPreOrderTraversal(BinTreeBT){if(BT){printf(“%d”,BT->Data);......