leetcode算法练习
110.平衡二叉树
题目链接
平衡二叉树是指任意一个节点的左右子树的高度差小于等于1
利用后序遍历 要得到左右子树的高度 返回给上一个节点
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
return getHeight(root) != -1;
}
// 返回值是int 左右子树高度
// 参数是根节点
// 若有任意一个节点的左右子树高度差超过了1 那整棵树必不是平衡二叉树 返回-1给上一个节点
private int getHeight(TreeNode root) {
// 终止条件是空节点 返回高度为0
if (root == null) {
return 0;
}
// 后序 左右根
// 左子树
int leftHeight = getHeight(root.left);
// 判断左子树是否是平衡二叉树
if (leftHeight == -1) {
return -1;
}
// 右子树
int rightHeight = getHeight(root.right);
if (rightHeight == -1) {
return -1;
}
// 左右子树高度差大于1 返回-1 表示已经不是平衡树了
if (Math.abs(leftHeight - rightHeight) > 1) {
return -1;
}
// 如果是平衡二叉树 那么该节点的高度应该是左子树和右子树高度最大的值 并+1(自身)
return Math.max(leftHeight, rightHeight) + 1;
}
}
257. 二叉树的所有路径
题目链接
本题需要回溯 利用前序遍历收集根节点到叶子节点的路径
从1出发 假设有一个容器存放路径 那么得到1-2-5 那么要把5弹出 2弹出 再回到1 得到1-3 这样弹出5和2的过程就是回溯的过程
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
if (root == null) {
return res;
}
List<Integer> paths = new ArrayList<>();
traversal(root, paths, res);
return res;
}
// 参数:根节点 paths数组存放单条路径 res数组存放最后结果
private void traversal(TreeNode root, List<Integer> paths, List<String> res) {
// 前序 根
paths.add(root.val);
// 遍历到叶子结点就可以结束了 不一定要到空节点
if (root.left == null && root.right == null) {
// 此时要输出结果了
// 把数字转换为String类型 并且遍历paths数组
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));
// 把结果放到res数组中
res.add(sb.toString());
return;
}
// *****
// 前序 根左右 根就是把节点里的数值添加进来的过程 因为每遍历一点就要把这个节点添加进来
// 根要写到第一行 因为终止条件是到叶子节点就结束了 若把中写到*****处 那就会漏掉叶子节点 因为处理叶子节点处直接return了
// 左 判断是否为空 防止root.left是空
if (root.left != null) {
traversal(root.left, paths, res);
// 回溯 弹出元素
paths.remove(paths.size() - 1);
}
if (root.right != null) {
traversal(root.right, paths, res);
// 回溯
paths.remove(paths.size() - 1);
}
}
}