第十七天| 第六章 二叉树part04 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和
一、110.平衡二叉树
-
题目链接:https://leetcode.cn/problems/balanced-binary-tree/
-
题目介绍:
-
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gEhmaOkY-1692948217787)(E:.STU\【JAVA】\LeetCode\第17天\平衡二叉树示例.png)]
- 思路:
- 获取高度:
-
- 明确使用后序遍历计算高度
- 递归结束的条件(遇到null,返回0)
- 每一层的逻辑是:如果左右子树的高度差大于1,就返回-1;如果左右子树的高度差小于等于1,就返回当前节点的高度;
-
- 最终判断根节点的高度,如果不等于-1,说明每一个节点都满足平衡二叉树高度差小于1的条件;如果等于-1,说明至少有一个节点不满足。
- 获取高度:
- 代码:
class Solution {
public boolean isBalanced(TreeNode root) {
// 如果不等于-1,说明每一个节点都满足平衡二叉树高度差小于1的条件;如果等于-1,说明至少有一个节点不满足。
return getHigh(root) != -1;
}
public int getHigh(TreeNode root){
// 1. 明确使用后序遍历计算高度
// 2. 递归结束的条件
if (root == null) {
return 0;
}
// 3. 每一层的逻辑是:
// 3.1 如果左右子树的高度差大于1,就返回-1
int leftHigh = getHigh(root.left);
int rightHigh = getHigh(root.right);
if (Math.abs(leftHigh - rightHigh) > 1) {
return -1;
}
// 3.2 如果左右子树的高度差小于等于1,就返回当前节点的高度;
return Math.max(leftHigh, rightHigh) + 1;
}
}
二、257. 二叉树的所有路径
-
题目链接:https://leetcode.cn/problems/binary-tree-paths/
-
题目介绍:
-
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
-
叶子节点 是指没有子节点的节点。
-
示例 1:
输入:root = [1,2,3,null,5] 输出:["1->2->5","1->3"]
-
-
思路:
- 因为要从根节点开始记录路径,所以一定是前序遍历
- 使用一个paths列表记录每一条路径,并且在找到叶子节点之后,进行回溯
- 这里要进行的回溯操作如下图所示:
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q45LLQYk-1692948217787)(二叉树的所有路径.png)]
- 每次找到叶子节点后,将当前的路径拷贝到result中。
-
代码:
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
// 搞一个result,把paths里的路径拷贝成;eetCode要求输出的样式
List<String> result = new ArrayList<>();
if (root == null) {
return result;
}
// 搞一个paths放每条路的路径
List<Integer> paths = new ArrayList<>();
traversal(root, paths, result);
return result;
}
public void traversal(TreeNode root, List<Integer> paths, List<String> result){
// 中:考虑到最终叶子节点也要放入paths中,所以先”中“
paths.add(root.val);
// 递归结束的条件,如果遇到叶子节点(左子节点和右子节点皆空),就return
// return之前把paths中的路径拷贝进result中
if (root.left == null && root.right == null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < paths.size() - 1; i++) {
sb.append(paths.get(i)).append("->");
}
sb.append(paths.get(paths.size() - 1));
result.add(sb.toString());
return;
}
// 如果左子节点不空
if (root.left != null) {
// 遍历左子节点
traversal(root.left, paths, result);
// 遍历完左子节点,要回溯,因为要找到当前节点的父节点,重新开始另一条新的路径
paths.remove(paths.size() - 1);
}
if (root.right != null) {
traversal(root.right, paths, result);
// 这里同理
paths.remove(paths.size() - 1);
}
}
}
三、404.左叶子之和
-
题目链接:https://leetcode.cn/problems/sum-of-left-leaves/
-
题目介绍:给定二叉树的根节点 root ,返回所有左叶子之和。
-
思路:
- 判断什么是左叶子节点?
- 遍历到父节点,判断付姐带你的左孩子不为空,且左孩子的左右孩子皆为空
- 核心判断:
- 递归:
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B4lcr50x-1692948217788)(左子节点递归核心代码.png)]
- 迭代:
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dbhqFLrQ-1692948217788)(左子节点迭代核心代码.png)]
-
代码:
(1)递归
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 0;
}
int leftSum = sumOfLeftLeaves(root.left); // 左
int rightSum = sumOfLeftLeaves(root.right); // 右
int midValue = 0;
if (root.left != null && root.left.left == null && root.left.right == null) {
midValue = root.left.val;
}
int sum = midValue + leftSum + rightSum; // 中
return sum;
}
}
(2)迭代(层序遍历)
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
int sum = 0;
Deque<TreeNode> queue = new LinkedList<>();
if (root != null) {
queue.offer(root);
}
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
TreeNode tempNode = queue.poll();
if (tempNode.left != null && tempNode.left.left == null && tempNode.left.right == null) {
sum += tempNode.left.val;
}
if (tempNode.left != null) {
queue.offer(tempNode.left);
}
if (tempNode.right != null) {
queue.offer(tempNode.right);
}
}
}
return sum;
}
}