对称的二叉树
什么是对称二叉树
根据题目的描述,我们先翻译一下什么是对称二叉树。
- 根节点的左右节点都不为空,且值相同
- 左右子节点的子节点不能只有一个存在,一个为空
- 左子节点的左子节点值 = 右子节点的右子节点值
- 左子节点的右子节点值 = 右子节点的左子节点值
- 如果左子节点的左子节点为空,那么右子节点也一定为空
这种遍历子节点的题目,我们可以使用bfs广度优先借用队列这种数据结构来做。我们只需要按照上述比较的顺序进行保存到队列中,依靠队列先进先出的特性进行比较就可以了。
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root.left);
q.offer(root.right);
while (!q.isEmpty()) {
TreeNode left = q.poll();
TreeNode right = q.poll();
if (left == null && right == null) continue;
if (left == null || right == null) return false;
if (left.val != right.val) return false;
q.offer(left.left);
q.offer(right.right);
q.offer(left.right);
q.offer(right.left);
}
return true;
}
}
二叉树层序遍历
借助队列实现层序遍历
class Solution {
private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) return res;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
//当前队列的长度,也就是该层的长度
//因为for循环能队列的长度会随之变化,所以需要size常量,先确定当前层的长度。
int size = q.size();
List<Integer> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
root = q.poll();
list.add(root.val);
if (root.left != null) q.offer(root.left);
if (root.right != null) q.offer(root.right);
}
res.add(list);
}
return res;
}
}
二叉树的层级遍历(层倒序)
这道题只需要在层序遍历的基础上,增加一个技巧,将遍历的层数据放在队列尾部,这样就可以实现将层是倒序输出的。
class Solution {
private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> levelOrderBottom(TreeNode root) {
if (root == null) return res;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
int size = q.size();
List<Integer> list = new ArrayList<>();
for (int i = 0; i< size; i++) {
root = q.poll();
list.add(root.val);
if (root.left != null) q.offer(root.left);
if (root.right != null) q.offer(root.right);
}
//核心代码,将结果放在队列尾部
res.add(0, list);
}
return res;
}
}
二叉树的锯齿遍历
解题思路
锯齿型实际上就是蛇形遍历,从左到右,再从右到走,依次到层级结束。 这里可以直接使用队列这种数据结构,使用一个标记位,当标记位是true的时候,我们倒序遍历,反之,我们正序遍历。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
if (root == null) return res;
boolean flag = false;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
int size = q.size();
List<Integer> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
root = q.poll();
if (flag) {
list.add(0, root.val);
} else {
list.add(root.val);
}
if (root.left != null) q.offer(root.left);
if (root.right != null) q.offer(root.right);
}
flag = !flag;
res.add(list);
}
return res;
}
}
二叉树最小深度
解题思路
BFS可以解决常见的最小、最短、最快等问题。因为bfs是按层遍历的,当遇到节点满足判断条件,就可以反馈。 最小深度也就意味着,有节点左&右节点同时为空,我们只需要使用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 {
public int minDepth(TreeNode root) {
if (root == null) return 0;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
int depth = 0;
while (!q.isEmpty()) {
int size = q.size();
depth++;
for (int i = 0; i < size; i++) {
root = q.poll();
if (root.left == null && root.right == null) return depth;
if (root.left != null) q.offer(root.left);
if (root.right != null) q.offer(root.right);
}
}
return depth;
}
}
二叉树的右视图
解题思路
BFS模板题,右视图实际上就是每层的最后一个,左视图就是每层的第一个。 使用 i == size - 1,这种判断条件就可以解决这个问题。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> rightSideView(TreeNode root) {
if (root == null) return new ArrayList<>();
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
List<Integer> res = new ArrayList<>();
while (!q.isEmpty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
root = q.poll();
if (i == size - 1) {
res.add(root.val);
}
if (root.left != null) q.offer(root.left);
if (root.right != null) q.offer(root.right);
}
}
return res;
}
}
二叉树每行的最大值
解题思路
标准层次遍历题,初始化一个最大值(Integer的最小值) 层序遍历更新每层的最大值,层次遍历结束后重置最大值
代码
/**
* 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) {
if (root == null) return new ArrayList<>();
List<Integer> res = new ArrayList<>();
int maxValue = Integer.MIN_VALUE;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
root = q.poll();
if (root.val > maxValue) {
maxValue = root.val;
}
if (root.left != null) q.offer(root.left);
if (root.right != null) q.offer(root.right);
}
res.add(maxValue);
maxValue = Integer.MIN_VALUE;
}
return res;
}
}
N叉树的最大深度
解题思路
可以使用bfs模板解决,按层级记录深度,遍历完成后深度就是最大的深度。
代码
/*
// 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 int maxDepth(Node root) {
if (root == null) return 0;
int depth = 0;
Queue<Node> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
int size = q.size();
depth++;
for (int i = 0; i < size; i++) {
root = q.poll();
for (Node cur : root.children) {
q.offer(cur);
}
}
}
return depth;
}
}