107.二叉树的层序遍历II
给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
List<List<Integer>> res = new ArrayList<>();
while (!queue.isEmpty()) {
int num = queue.size();
List<Integer> list = new ArrayList<>();
while (num-- > 0) {
TreeNode tmp = queue.poll();
list.add(tmp.val);
if (tmp.left != null) {
queue.add(tmp.left);
}
if (tmp.right != null) {
queue.add(tmp.right);
}
}
res.add(0, list);
}
// Collections.reverse(res);
return res;
}
}
res.add(index, list)可以使用这种写法控制插入的具体位置,也可以在最后反转一下列表
时间复杂度、空间复杂度均为O(n)
199.二叉树的右视图
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
输入: [1,2,3,null,5,null,4]
输出: [1,3,4]
public List<Integer> rightSideView(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
List<Integer> res = new ArrayList<>();
while (!queue.isEmpty()) {
int size = queue.size();
int idx = size;
while (idx > 0) {
TreeNode tmp = queue.poll();
if (size == idx) {
res.add(tmp.val);
}
if (tmp.right != null) {
queue.add(tmp.right);
}
if (tmp.left != null) {
queue.add(tmp.left);
}
idx--;
}
}
return res;
}
时间复杂度、空间复杂度均为O(n)
637.二叉树的层平均值
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值
public List<Double> averageOfLevels(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
List<Double> res = new ArrayList<>();
while (!queue.isEmpty()) {
int num = queue.size();
int count = num;
double sum = 0.0;
while (num-- > 0) {
TreeNode tmp = queue.poll();
sum += tmp.val;
if (tmp.left != null) {
queue.add(tmp.left);
}
if (tmp.right != null) {
queue.add(tmp.right);
}
}
res.add(sum / count);
}
return res;
}
429.N叉树的层序遍历
*给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]*
public List<List<Integer>> levelOrder(Node root) {
if (root == null) {
return new ArrayList<>();
}
Queue<Node> queue = new ArrayDeque<>();
queue.add(root);
List<List<Integer>> res = new ArrayList<>();
while (!queue.isEmpty()) {
int num = queue.size();
List<Integer> list = new ArrayList<>();
while (num-- > 0) {
Node tmp = queue.poll();
list.add(tmp.val);
for (Node child : tmp.children) {
if (child != null) {
queue.add(child);
}
}
}
res.add(list);
}
return res;
}
515.在每个树行中找最大值
public List<Integer> largestValues(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
List<Integer> res = new ArrayList<>();
while (!queue.isEmpty()) {
int num = queue.size();
List<Integer> list = new ArrayList<>();
int largest = Integer.MIN_VALUE;
while (num-- > 0) {
TreeNode tmp = queue.poll();
largest = Math.max(largest, tmp.val);
if (tmp.right != null) {
queue.add(tmp.right);
}
if (tmp.left != null) {
queue.add(tmp.left);
}
}
res.add(largest);
}
return res;
}
116.填充每个节点的下一个右侧节点指针
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
初始状态下,所有 next 指针都被设置为 NULL
public Node connect(Node root) {
if (root == null) {
return null;
}
Node res = root;
Queue<Node> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
Node node = queue.poll();
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
while (size > 1) {
Node tmp = queue.poll();
if (tmp.left != null) {
queue.add(tmp.left);
}
if (tmp.right != null) {
queue.add(tmp.right);
}
node.next = tmp;
node = tmp;
size--;
}
}
return res;
}
117.填充每个节点的下一个右侧节点指针
与上一题区别是,本题给出的不一定是完美二叉树,每个节点不一定有俩子节点,上一题每个节点都肯定有俩子节点
class Solution {
public Node connect(Node root) {
if (root == null) {
return null;
}
Node res = root;
Queue<Node> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
Node node = queue.poll();
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
while (size > 1) {
Node tmp = queue.poll();
if (tmp.left != null) {
queue.add(tmp.left);
}
if (tmp.right != null) {
queue.add(tmp.right);
}
node.next = tmp;
node = tmp;
size--;
}
}
return res;
}
}
104.二叉树的最大深度
迭代:
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
int res = 0;
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
res++;
int size = queue.size();
while (size-- > 0) {
TreeNode tmp = queue.poll();
if (tmp.left != null) {
queue.add(tmp.left);
}
if (tmp.right != null) {
queue.add(tmp.right);
}
}
}
return res;
}
递归:
class Solution {
int maxDepth = 0;
public int maxDepth(TreeNode root) {
dfs(root, 0);
return maxDepth;
}
private void dfs(TreeNode node, int depth) {
if (node == null) {
return;
}
maxDepth = Math.max(depth + 1, maxDepth);
dfs(node.left, depth + 1);
dfs(node.right, depth + 1);
}
}
递归法时间复杂度为O(n),空间复杂度为O(h)及递归过程中的栈空间取决于递归的深度,所以空间复杂度等于二叉树的高度
111.二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
class Solution {
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
int minDepth = 0;
while (!queue.isEmpty()) {
int size = queue.size();
minDepth++;
while (size-- > 0) {
TreeNode tmp = queue.poll();
if (tmp.left == null && tmp.right == null) {
return minDepth;
}
if (tmp.left != null) {
queue.add(tmp.left);
}
if (tmp.right != null) {
queue.add(tmp.right);
}
}
}
return minDepth;
}
}
递归:
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 1;
}
int leftDepth = minDepth(root.left);
int rightDepth = minDepth(root.right);
if (root.left == null || root.right == null) {
return leftDepth + rightDepth + 1;
}
return Math.min(leftDepth, rightDepth) + 1;
}
递归写法没想到,讲解如下:
一个节点,如果本身是null,该层深度贡献0,如果本身存在,左右节点均不存在,贡献本身的深度1,若左右节点存在一个(不能直接比较min(leftD,rightD),因为答案肯定是0),那leftD和rightD中肯定有一个是0,所以返回leftD+rightD+1,如果两个子树均存在,则比较leftD和rightD取最小值+1