LeetCode 110 平衡二叉树
思路
平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 我们可以遍历每个节点,获取其每个子树的高度,就可以得到当前树是否为平衡二叉树,且当前树的高度就是左右子树高度的最大值+1 故可以设计一个递归函数,获得树的高度:
- 递归函数的参数和返回值
- 全局变量:flag标识是否找到非平衡二叉树的节点
- 参数:根节点
- 返回值:树的高度
- 递归函数的结束条件 根节点为空,返回0
- 单层递归逻辑
- 对节点的左右子节点分别递归调用,得到子树高度
- 计算当前树是否为平衡二叉树
- 如果是平衡二叉树,返回当前树的高度
- 如果不是,把flag置false,返回当前树的高度 主函数中要调用递归函数,返回flag
解法
class Solution {
boolean flag = true;
public boolean isBalanced(TreeNode root) {
height(root);
return flag;
}
public int height(TreeNode root) {
if (root == null) {
return 0;
}
int height1 = height(root.left);
int height2 = height(root.right);
if (Math.abs(height2 - height1) > 1) {
flag = false;
}
return Math.max(height1, height2)+1;
}
}
LeetCode 257 二叉树的所有路径
思路
路径是所有从根节点到叶子节点的路径。我们可以前序遍历节点,在不断递归的过程中构建出路径。但从一个路径到另一个路径需要回溯,所以在递归函数返回前,要对路径进行还原 考虑递归三要素:
- 递归函数的参数和返回值:
- 全局变量:结果集合result
- 参数:根节点root,当前路径path
- 返回值:空
- 递归函数的结束条件: 当节点为空,直接返回
- 单层递归逻辑:
- 把节点的值放进path里
- 如果节点是叶子节点,把path放入结果集
- 如果节点不是叶子,对左右子节点递归调用
- 还原path,返回
解法
class Solution {
List<String> result;
public List<String> binaryTreePaths(TreeNode root) {
result = new ArrayList<>();
List<String> path = new ArrayList<>();
traverse(root, path);
return result;
}
public void traverse(TreeNode root, List<String> path) {
if (root == null) {
return ;
}
path.add(String.valueOf(root.val));
if (root.left == null && root.right == null) {
result.add(String.join("->", path));
}
else {
traverse(root.left, path);
traverse(root.right, path);
}
path.remove(path.size()-1);
}
}
LeetCode 404 左叶子之和
思路
一个叶子是否是左叶子,要处于其父母节点才能判断。 所以递归遍历所有可能有左叶子节点的点,把左叶子的值加到全局变量上
考虑递归三要素:
- 递归函数的参数和返回值
- 全局变量:所有的左叶子之和sum
- 参数:根节点root
- 返回值:空
- 递归函数的结束条件: 当节点为空,返回
- 单层递归逻辑
- 如果节点有左叶子,把左叶子的值加到sum中.左叶子下不会再有左叶子,所以只要对右子节点递归
- 如果节点没有左叶子,对左右子节点递归调用
解法
class Solution {
int sum;
public int sumOfLeftLeaves(TreeNode root) {
sum = 0;
traverse(root);
return sum;
}
public void traverse(TreeNode root) {
if (root == null) {
return ;
}
if (root.left != null && root.left.left == null && root.left.right == null) {
sum += root.left.val;
traverse(root.right);
}
else {
traverse(root.left);
traverse(root.right);
}
}
}
LeetCode 222 完全二叉树的节点个数
思路
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(从第 0 层开始),则该层包含 到 个节点。
经过观察可以发现,完全二叉树每个叶子节点都存在于一个满二叉树中。而满二叉树的节点数量可以通过公式计算。所以我们在递归到一个满二叉树时,可以直接计算节点个数,不用再往下递归。
那么如何判断完全二叉树中的一个子树是否是满二叉树呢? 从根节点开始,一直向左递归和一直向右递归如果深度一样,那么它就是满二叉树。 从整体来看,方便计算的满二叉树节点个数在底层,所以可以在回溯时把非满二叉树的根节点加在节点个数中。
考虑递归三要素:
- 递归函数的参数和返回值
- 参数:根节点
- 返回值:树的节点个数
- 递归函数的结束条件
- 当前节点为空,返回0
- 当前树为满二叉树,计算出节点个数直接返回
- 单层递归的逻辑
- 递归对左右子节点调用,得到左右子树的节点个数leftCount,rightCount
- 返回leftCount+rightCount+1
解法
class Solution {
public int countNodes(TreeNode root) {
if (root == null)
return 0;
}
TreeNode leftNode = root.left;
TreeNode rightNode = root.right;
int leftDepth = 1;
int rightDepth = 1;
while (leftNode != null) {
leftNode = leftNode.left;
leftDepth++;
}
while (rightNode != null) {
rightNode = rightNode.right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (int)Math.pow(2, rightDepth)-1;
}
int leftCount = countNodes(root.left);
int rightCount = countNodes(root.right);
return leftCount+rightCount+1;
}
}
今日收获总结
今日学习2.5小时,二叉树的很多题目用递归方法解决还是很方便的~