102.二叉树的层序遍历
● 力扣题目链接
● 给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
思路
● 循环内部是,先计算size,然后逐层弹出节点,因此需要先把头结点加进去
代码
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList();
Deque<TreeNode> queue = new ArrayDeque();
if (root == null) return res;
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList();
while (size > 0) {
TreeNode temp = queue.removeFirst();
size--;
list.add(temp.val);
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
res.add(list);
}
return res;
}
}
107. 二叉树的层序遍历 II
● 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new ArrayList();
Deque<TreeNode> queue = new ArrayDeque();
if (root == null) return res;
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList();
while (size-- > 0) {
TreeNode temp = queue.removeFirst();
list.add(temp.val);
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
res.add(0, list);
}
return res;
}
}
199. 二叉树的右视图
● 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new ArrayList();
Deque<TreeNode> queue = new ArrayDeque();
if (root == null) return res;
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
TreeNode temp = queue.removeFirst();
if (size == 0) res.add(temp.val);
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
}
return res;
}
}
637. 二叉树的层平均值
● 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> res = new ArrayList();
Deque<TreeNode> queue = new ArrayDeque();
if (root == null) return res;
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
int t = size;
double sum = 0;
while (size-- > 0) {
TreeNode temp = queue.removeFirst();
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
sum += temp.val;
if (size == 0) res.add(sum / t);
}
}
return res;
}
}
429. N 叉树的层序遍历
● 给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
● 树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> res = new ArrayList();
if (root == null) return res;
Deque<Node> queue = new ArrayDeque();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList();
while (size-- > 0) {
Node temp = queue.removeFirst();
list.add(temp.val);
for (Node node : temp.children) {
if (node != null) queue.addLast(node);
}
}
res.add(list);
}
return res;
}
}
515. 在每个树行中找最大值
● 给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
class Solution {
public List<Integer> largestValues(TreeNode root) {
List<Integer> res = new ArrayList();
if (root == null) return res;
Deque<TreeNode> queue = new ArrayDeque();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
int max = Integer.MIN_VALUE;
while (size-- > 0) {
TreeNode temp = queue.removeFirst();
max = Math.max(temp.val, max);
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
res.add(max);
}
return res;
}
}
116. 填充每个节点的下一个右侧节点指针
● 给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
class Solution {
public Node connect(Node root) {
Deque<Node> queue = new ArrayDeque();
if (root == null) return root;
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
Node temp = queue.removeFirst();
if (size == 0) temp.next = null;
else temp.next = queue.peekFirst();
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
}
return root;
}
}
117. 填充每个节点的下一个右侧节点指针 II
● 给定一个二叉树:填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。
● 初始状态下,所有 next 指针都被设置为 NULL 。
class Solution {
public Node connect(Node root) {
if (root == null) return root;
Deque<Node> queue = new ArrayDeque();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
Node temp = queue.removeFirst();
if (size != 0) temp.next = queue.peekFirst();
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
}
return root;
}
}
104. 二叉树的最大深度
● 给定一个二叉树 root ,返回其最大深度。
● 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
class Solution {
public int maxDepth(TreeNode root) {
Deque<TreeNode> queue = new ArrayDeque();
if (root == null) return 0;
int height = 0;
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
TreeNode temp = queue.removeFirst();
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
height++;
}
return height;
}
}
111. 二叉树的最小深度
● 给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
● 说明:叶子节点是指没有子节点的节点。
class Solution {
public int minDepth(TreeNode root) {
if (root == null) return 0;
Deque<TreeNode> queue = new ArrayDeque();
int height = 0;
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
height++;
while (size-- > 0) {
TreeNode temp = queue.removeFirst();
// 注意的是,只有左右节点都空,才到了叶子节点,这时直接返回height
if (temp.left == null && temp.right == null) return height;
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
}
return height;
}
}
226.翻转二叉树
● 力扣题目链接
● 翻转一棵二叉树。
思路
● 先写递归终止条件
● invertTree(root.left)返回值是翻转之后的左子树,返回2
● invertTree(root.right)返回值是翻转之后的右子树,返回7
● 接下来我们需要把7放到4的左子节点位置,2放到右子节点位置
代码
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
// 需要保存一下左子树的结果
TreeNode temp = invertTree(root.left);
root.left = invertTree(root.right);
root.right = temp;
return root;
}
}
// 层序遍历
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return root;
Deque<TreeNode> queue = new ArrayDeque();
queue.addLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- > 0) {
TreeNode temp = queue.removeFirst();
reverse(temp);
if (temp.left != null) queue.addLast(temp.left);
if (temp.right != null) queue.addLast(temp.right);
}
}
return root;
}
private void reverse(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
}
101. 对称二叉树
● 力扣题目链接
● 给定一个二叉树,检查它是否是镜像对称的。
思路
● 可以判断左右子树是否对称
○ 如果都空返回true,一个空返回false,值不等返回false
○ 值等,继续要看左左右右、左右右左子树是否对称
● 可以使用双端队列处理
● 注意:Java中add和remove(遇到空报错),offer和poll遇到空不报错(返回false和null)
代码
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return isSym(root.left, root.right);
}
private boolean isSym(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) return true;
if (root1 == null || root2 == null) return false;
if (root1.val != root2.val) return false;
return isSym(root1.left, root2.right) && isSym(root1.right, root2.left);
}
}
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
Deque<TreeNode> deque = new LinkedList();
deque.offerLast(root.left);
deque.offerFirst(root.right);
while (!deque.isEmpty()) {
TreeNode left = deque.pollLast();
TreeNode right = deque.pollFirst();
if (left == null && right == null) continue;
if (left == null || right == null || left.val != right.val) return false;
deque.offerLast(left.left);
deque.offerLast(left.right);
deque.offerFirst(right.right);
deque.offerFirst(right.left);
}
return true;
}
}
100. 相同的树
● 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
● 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
Deque<TreeNode> deque = new LinkedList();
deque.offerLast(p);
deque.offerFirst(q);
while (!deque.isEmpty()) {
TreeNode left = deque.pollLast();
TreeNode right = deque.pollFirst();
if (left == null && right == null) continue;
if (left == null || right == null || left.val != right.val) return false;
deque.offerLast(left.left);
deque.offerLast(left.right);
deque.offerFirst(right.left);
deque.offerFirst(right.right);
}
return true;
}
}
572. 另一棵树的子树
● 给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
● 二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if (subRoot == null) return true;
if (root == null) return false;
// 相同,或者是左子树的子树,或者是右子树的子树
return isSame(root, subRoot) || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}
// 判断两树相同
private boolean isSame(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) return true;
if (root1 == null || root2 == null || root1.val != root2.val) return false;
return isSame(root1.left, root2.left) && isSame(root1.right, root2.right);
}
}