day17:二叉树:110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和
LeetCode 110.平衡二叉树
左子树和右子树的高度差的绝对值不大于1,如图:
树1的左子树的高度为3,右子树为2,高度差为1,所以是平衡二叉树
树2的左子树的高度为3,右子树为3,高度差为0,所以也是平衡二叉树
树3的左子树的高度为3,右子树为1,高度差为2,大于1,所以不是平衡二叉树
题目链接:
文章讲解:
https://programmercarl.com/0110.%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91.html
视频讲解:
https://www.bilibili.com/video/BV1Ug411S7my/
思路和解法:
-
创建一个递归函数,该函数接受一个树节点作为参数,返回该节点所在子树的高度。如果子树不是高度平衡的,返回-1表示不平衡。
-
在递归函数中,首先判断根节点是否为空,如果为空则返回高度0(空树也是平衡的)。
-
递归地计算左子树的高度,调用递归函数并传入左子节点作为参数。
-
递归地计算右子树的高度,调用递归函数并传入右子节点作为参数。
-
如果左子树或右子树的高度为-1,或者它们的高度差超过1,则返回-1,表示当前子树不平衡。
-
如果左子树和右子树都是平衡的,并且它们的高度差不超过1,则返回当前子树的高度,即
1 + Math.Max(leftHeight, rightHeight)
。 -
在主函数中,调用递归函数并传入根节点,然后检查返回的值是否为-1。如果返回-1,表示整棵树不平衡;否则,表示树是平衡的。
-
public class Solution { public bool IsBalanced(TreeNode root) { return CheckBalance(root) != -1; } public int CheckBalance(TreeNode node) { if(node == null) return 0; int leftHeight = CheckBalance(node.left); if(leftHeight == -1) return -1; int rightHeight = CheckBalance(node.right); if(rightHeight == -1) return -1; if(Math.Abs(leftHeight - rightHeight) > 1) return -1; return 1 + Math.Max(leftHeight, rightHeight); } }
LeetCode 257. 二叉树的所有路径
题目链接:
文章讲解:
https://programmercarl.com/0257.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%89%80%E6%9C%89%E8%B7%AF%E5%BE%84.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频讲解:
https://www.bilibili.com/video/BV1ZG411G7Dh/
思路和解法:
- 创建一个列表
result
,用于存储所有从根节点到叶子节点的路径。 - 创建一个递归函数,该函数接受当前节点、当前路径(作为字符串列表)作为参数,并进行深度优先搜索。
- 在递归函数中,首先检查当前节点是否为空。如果为空,直接返回。
- 如果当前节点不为空,将当前节点的值添加到当前路径中,将其转化为字符串。
- 检查当前节点是否为叶子节点(左子树和右子树都为空)。如果是叶子节点,则将当前路径添加到
result
列表中,并返回。 - 如果当前节点不是叶子节点,继续递归调用左子树和右子树。递归调用时,需要传递当前节点的左子节点和右子节点作为参数,以及当前路径的副本(因为每个子树都有自己的路径)。
- 在主函数中,调用递归函数,将根节点作为起始节点和一个空列表作为当前路径的初始状态。
- 返回
result
列表,其中包含了所有从根节点到叶子节点的路径。
public class Solution {
public IList<string> BinaryTreePaths(TreeNode root) {
List<string> result = new List<string>();
if (root == null)
return result;
// 定义递归函数
void DFS(TreeNode node, List<string> currentPath)
{
if (node == null)
return;
currentPath.Add(node.val.ToString());
if (node.left == null && node.right == null)
{
// 叶子节点,将当前路径添加到结果中
result.Add(string.Join("->", currentPath));
}
else
{
// 继续遍历左子树和右子树
DFS(node.left, new List<string>(currentPath));
DFS(node.right, new List<string>(currentPath));
}
}
// 调用递归函数
DFS(root, new List<string>());
return result;
}
}
LeetCode 404.左叶子之和
题目链接:
文章讲解:
https://programmercarl.com/0404.%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频讲解:
https://www.bilibili.com/video/BV1GY4y1K7z8/
思路和解法:
- 创建一个整数变量
sum
,用于累加左叶子节点的值,并初始化为0。 - 创建一个递归函数,该函数接受当前节点作为参数,并进行深度优先搜索。
- 在递归函数中,首先检查当前节点是否为空。如果为空,直接返回。
- 如果当前节点不为空,检查当前节点的左子节点是否存在且为叶子节点。如果是左叶子节点,则将其值累加到
sum
变量中。 - 继续递归调用左子树和右子树。递归调用时,分别传递当前节点的左子节点和右子节点作为参数。
- 在主函数中,调用递归函数,将根节点作为起始节点。
- 返回
sum
变量的值,它包含了所有左叶子节点的和。
public class Solution {
public int SumOfLeftLeaves(TreeNode root) {
int sum = 0;
// 定义递归函数
void DFS(TreeNode node)
{
if (node == null)
return;
if (node.left != null && node.left.left == null && node.left.right == null)
{
// 如果左子节点存在且是叶子节点,累加其值到sum
sum += node.left.val;
}
// 继续遍历左子树和右子树
DFS(node.left);
DFS(node.right);
}
// 调用递归函数
DFS(root);
return sum;
}
}
}
// 继续遍历左子树和右子树
DFS(node.left);
DFS(node.right);
}
// 调用递归函数
DFS(root);
return sum;
}
}