代码随想录算法训练营Day16 | 104.二叉树的最大深度、559.N叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

104.二叉树的最大深度

层序遍历打十个之一。使用一个变量记录层数,遍历每一层的时候该变量+1即可。

层序遍历写法:

int maxDepth0(TreeNode* root) {
	if (!root)
		return 0;
	TreeNode* cur;
	queue<TreeNode*> que;
	int size;
	int ans = 0;

	que.push(root);
	while (!que.empty()) {
		++ans;
		size = que.size();
		while (size--) {
			cur = que.front();
			que.pop();
			if (cur->left)
				que.push(cur->left);
			if (cur->right)
				que.push(cur->right);
		}
	}
	return ans;
}

递归遍历思路:

· 返回值类型:使用int型返回深度值

· 传入参数:传入一个节点指针

· 终止条件:遇到空节点则向上返回0

· 单层逻辑:计算左右子树的深度,取较大值即可

递归写法: 

int getHeight(TreeNode* cur) {
	if (!cur)
		return 0;
	int left = getHeight(cur->left);
	int right = getHeight(cur->right);
	int height = std::max(left, right) + 1;
	return height;
}

int maxDepth(TreeNode* root) {
	return getHeight(root);
}

559.N叉树的最大深度

与二叉树最大深度思路一致,每一层迭代/递归时遍历所有节点即可

层序遍历写法:

int maxDepth(Node* root) {
	if (!root)
		return 0;
	Node* cur;
	queue<Node*> que;
	int size;
	int ans = 0;

	que.push(root);
	while (!que.empty()) {
		++ans;
		size = que.size();
		while (size--) {
			cur = que.front();
			que.pop();
			for (auto child : cur->children) {
				if (child)
					que.push(child);
			}
		}
	}
	return ans;
}

111.二叉树的最小深度

 注意最小深度的定义,一定要到达叶节点才能算最小深度,即存在左/右任一子树不能直接返回。

层序遍历的判断条件比较简单,存在两个孩子与只存在某一个节点的逻辑可以写在一起

层序遍历写法:

int minDepth(TreeNode* root) {
	if (!root)
		return 0;
	queue<TreeNode*> que;
	int size;
	int min = 0;
	TreeNode* cur;

	que.push(root);
	while (!que.empty()) {
		++min;
		size = que.size();
		while (size--) {
			cur = que.front();
			que.pop();
			// 存在任一孩子说明不是叶子节点
			if (cur->left || cur->right) {
				if(cur->left)
					que.push(cur->left);
				if(cur->right)
					que.push(cur->right);
			}
			// 发现叶子节点直接返回当前深度
			else {
				return min;
			}	
		}
	}
	return min;
}

递归写法需要对每种情况进行分类讨论,对于空孩子不计入。

个人认为写起来做好分类讨论即可,不要被前中后序给束缚住思路。

递归遍历写法:

int getHeight(TreeNode* cur) {
	if (!cur)
		return 0;
	int height;
	// 只有一边子树为空时,该子树不记录
	if (cur->left && !cur->right)
		height = getHeight(cur->left) + 1;
	else if (!cur->left && cur->right)
		height = getHeight(cur->right) + 1;
	else if (cur->left && cur->right) {
		int left = getHeight(cur->left);
		int right = getHeight(cur->right);
		height = std::min(left, right) + 1;
	}
	// 左右子树都为空,该节点为叶节点,其高度为1 
	else {
		height = 1;
	}
	return height;
}

int minDepth(TreeNode* root) {
	return getHeight(root);
}

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

普通二叉树递归思路:

· 返回值:使用int型返回节点个数

· 传入参数:传入一个节点指针

· 终止条件:遇到空节点返回节点个数0

· 单层逻辑:分别计算当层节点左右子树的节点数,再算上自己1个节点进行返回

int getNum(TreeNode* cur) {
	if (!cur)
		return 0;
	int left = getNum(cur->left);			// 左
	int right = getNum(cur->right);		// 右
	int num = left + right + 1;				// 中
	return num;
}	

int countNodes(TreeNode* root) {
	int ans = getNum(root);
	return ans;
}

 利用完全二叉树性质的思路:

完全二叉树中大部分子树都是满二叉树,而满二叉树的节点数能够使用公式计算

· 返回值:使用int型返回节点个数

· 传入参数:传入一个节点指针

· 终止条件:

        1、遇到空节点返回节点个数0

        2、如果该子树是一个满二叉树,直接使用公式计算其节点数并返回

· 单层逻辑:分别计算当层节点左右子树的节点数,再算上自己1个节点进行返回

int getNum(TreeNode* cur) {
	// 以下都是返回条件
	// 返回条件除了判断是否是空节点外还有判断该子树是否是满二叉树
	if (!cur)
		return 0;
	TreeNode* left = cur->left;
	TreeNode* right = cur->right;
	int leftDepth = 1;
	int rightDepth = 1;
	// 一路向左计算深度
	while (left) {
		left = left->left;
		++leftDepth;
	}
	// 一路向右计算深度
	while (right) {
		right = right->right;
		++rightDepth;
	}
	// 如果两边深度相同说明是满二叉树,根据公式计算节点数并返回
	// 公式:节点数 = 2^leftDepth - 1
	if (leftDepth == rightDepth) {
		return (1 << leftDepth) - 1;		// 左移运算符
	}

	int leftNum = getNum(cur->left);		// 左
	int rightNum = getNum(cur->right);		// 右
	int sum = leftNum + rightNum + 1;		// 中,左右节点求和,加上自己一个节点
	return sum;
}

int countNodes(TreeNode* root) {
	return getNum(root);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值