@[TOC](代码随想录算法训练营第15天 | 二叉树层序遍历(8题)、226.翻转二叉树、101.对称二叉树)
二叉树层序遍历 有八道题
102.二叉树的层序遍历
题目:102.二叉树的层序遍历
文档讲解:代码随想录-102.二叉树的层序遍历
视频讲解:哔哩哔哩-102.二叉树的层序遍历
状态/时间:没写出来/三十分钟
思路:
利用队列跟BFS广度优先。
代码:
/**
* 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 {
//BFS--迭代方式--借助队列
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) {
return res;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
while (size-- > 0) {
TreeNode node = queue.peek();
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
list.add(queue.poll().val);
}
res.add(list);
}
return res;
}
}
注意:
2.二叉树的层次遍历 II 107
思路
直接插入到头部,这样可以不用反转,插入是O(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 List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) {
return res;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
while (size-- > 0) {
TreeNode node =queue.peek();queue.poll();
list.add(node.val);
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
// 插入到头部,这样不用反转O(1)
res.addFirst(list);
}
return res;
}
}
3. 二叉树的右视图 199
思路:
其实就是每层的最后一个结点,记录下来就好了。
代码:
// /**
// * 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<Integer> rightSideView(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
Deque<TreeNode> queue = new LinkedList<TreeNode>();
queue.offerLast(root);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.pollFirst();
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
if (i == size - 1) {
res.add(node.val);
}
}
}
return res;
}
}
注意:
4. 637.二叉树的层平均值 637
思路:
只需要计算平均值即可,我这里有点笨。第二个while应该用for比较好。
代码:
/**
* 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<Double> averageOfLevels(TreeNode root) {
List<Double> res = new ArrayList<Double>();
if (root == null) {
return res;
}
Deque<TreeNode> deque = new LinkedList<TreeNode>();
deque.add(root);
while (!deque.isEmpty()) {
double avg = 0.0;
int size = deque.size();
int size1 = deque.size();
while (size-- > 0) {
TreeNode node = deque.poll();
avg += node.val;
if (node.left != null) {
deque.add(node.left);
}
if (node.right != null) {
deque.add(node.right);
}
}
res.add(avg / size1);
}
return res;
}
}
注意:
5. N叉树的层序遍历 429
思路:
把判断左右子树的操作改为遍历所有子树
代码:
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) {
return res;
}
Deque<Node> deque = new LinkedList<Node>();
deque.add(root);
while (!deque.isEmpty()) {
int size = deque.size();
List<Integer> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
Node node = deque.poll();
list.add(node.val);
if (node.children != null) {
for (Node child : node.children) {
deque.add(child);
}
}
}
res.add(list);
}
return res;
}
}
注意:
6. 在每个树行中找最大值 116
思路:
找到最大的值,添加到res里面即可
代码:
/**
* 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<Integer> largestValues(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
Deque<TreeNode> deque = new LinkedList<TreeNode>();
deque.add(root);
while (!deque.isEmpty()) {
int size = deque.size();
int temp = Integer.MIN_VALUE;
while (size-- > 0) {
TreeNode node = deque.poll();
if (node.val > temp) {
temp = node.val;
}
if (node.left != null) {
deque.add(node.left);
}
if (node.right != null) {
deque.add(node.right);
}
}
res.add(temp);
}
return res;
}
}
注意:
7. 填充每个节点的下一个右侧节点指针 116
思路:
思路还不是很清晰
代码:
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
if (root == null) {
return root;
}
Deque<Node> deque = new LinkedList<Node>();
deque.add(root);
while (!deque.isEmpty()) {
int size = deque.size();
Node cur = deque.poll();
if (cur.left != null) {
deque.add(cur.left);
}
if (cur.right != null) {
deque.add(cur.right);
}
for (int i = 1; i < size; i++) {
Node next = deque.poll();
if (next.left != null) deque.add(next.left);
if (next.right != null) deque.add(next.right);
cur.next = next;
cur = next;
}
}
return root;
}
}
注意:
8. 填充每个节点的下一个右侧节点指针II 117
思路:
思路还不是很清晰
代码:
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
if (root == null) {
return root;
}
Deque<Node> deque = new LinkedList<Node>();
deque.add(root);
while (!deque.isEmpty()) {
int size = deque.size();
Node cur = deque.poll();
if (cur.left != null) {
deque.add(cur.left);
}
if (cur.right != null) {
deque.add(cur.right);
}
for (int i = 1; i < size; i++) {
Node next = deque.poll();
if (next.left != null) deque.add(next.left);
if (next.right != null) deque.add(next.right);
cur.next = next;
cur = next;
}
}
return root;
}
}
注意:
226.翻转二叉树
题目:226.翻转二叉树
文档讲解:代码随想录-226.翻转二叉树
视频讲解:哔哩哔哩-226.翻转二叉树
状态/时间:没写出来/三十分钟
思路:
定义一个swap方法,通过左换右,右换左,再递归调用即可实现反转二叉树。
代码:
/**
* 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 TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
// 前序的方式
swap(root);
invertTree(root.left);
invertTree(root.right);
return root;
}
public void swap(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
}
注意:
101.对称二叉树
题目:101.对称二叉树
文档讲解:代码随想录-101.对称二叉树
视频讲解:哔哩哔哩-101.对称二叉树
状态/时间:没写出来/三十分钟
思路:
判断二叉树的子树的内测和外侧是否相等,只有两个相等才能是对称。同时也要考虑子树是否,左有子树,右没有子树。右有子树,左没有子树的情况。
以及他们的值是否相等,最后还有两边子树都为空的情况。
代码:
/**
* 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 isSymmetric(TreeNode root) {
if (root == null) return false;
return compare(root.left, root.right);
}
public boolean compare(TreeNode left, TreeNode right) {
// 左 不等于 右
if (left == null && right != null) {
return false;
} else if (left != null && right == null) {
return false;
} else if (left == null && right == null) {
return true;
} else if (left.val != right.val) {
return false;
}
// 外侧
boolean outside = compare(left.left, right.right);
// 内测
boolean inside = compare(left.right, right.left);
// 要两个都相等
boolean result = outside && inside;
return result;
}
}
注意: