目录
102.二叉树层序遍历
解题思路
-
借助队列,先进先出,根据每层的长度进行循环模拟加入队列
Java代码:
/**
* 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 {
List<List<Integer>> res = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
checkFunc(root);
return res;
}
//层序遍历-迭代法(BFS)借助队列-先进先出
public void checkFunc(TreeNode root) {
if (root == null) {
return;
}
Deque<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> list = new ArrayList<>();
int len = queue.size();
while (len > 0) {
TreeNode node = queue.poll();
//添加当前层序节点的值到list数组中
list.add(node.val);
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
len--;
}
res.add(list);
}
}
}
107.二叉树程序遍历II
解题思路
-
与二叉树的程序遍历唯一区别是,返回的结果翻转一下
-
使用addFirst函数即可
Java代码
/**
* 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) {
LinkedList<List<Integer>> res = new LinkedList<List<Integer>>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return res;
}
que.offer(root);
while (!que.isEmpty()) {
int len = que.size();
List<Integer> list = new ArrayList<>();
while (len > 0) {
TreeNode node = que.poll();
list.add(node.val);
//当前层序的左右孩子 添加到队列中
if (node.left != null) {
que.offer(node.left);
}
if (node.right != null) {
que.offer(node.right);
}
len--;
}
//每次添加在数组的前面
res.addFirst(list);
}
return res;
}
}
199.二叉树的右视图
解题思路
-
判断是否遍历到单层的最后一个元素,是的话添加到数组中
Java代码
/**
* 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<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return res;
}
que.offer(root);
while (!que.isEmpty()) {
int len = que.size();
for (int i =0; i < len; i++) {
TreeNode node = que.poll();
//当前层序的左右孩子 添加到队列中
if (node.left != null) {
que.offer(node.left);
}
if (node.right != null) {
que.offer(node.right);
}
//遍历到右孩子时加入数组中
if (i == len - 1) {
res.add(node.val);
}
}
}
return res;
}
}
637.二叉树的平均值
解题思路
-
记录每层元素的sum和,然后/当前层的长度
Java代码
/**
* 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<>();
if (root == null) {
return res;
}
Deque<TreeNode> que = new LinkedList<>();
que.offer(root);
while (!que.isEmpty()) {
int len = que.size();
double sum = 0.0;
for (int i =0; i < len; i++) {
TreeNode node = que.poll();
sum += node.val;
//当前层序的左右孩子 添加到队列中
if (node.left != null) {
que.offer(node.left);
}
if (node.right != null) {
que.offer(node.right);
}
}
res.add(sum/len);
}
return res;
}
}
429.N叉树的层序遍历
解题思路
-
N叉树不再是左右孩子,而是一个Node孩子数组,循环遍历孩子数组,添加队列中
Java代码
/*
// 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<List<Integer>>();
Deque<Node> que = new LinkedList<>();
if (root ==null) {
return res;
}
que.offerLast(root);
while (!que.isEmpty()) {
int len = que.size();
List<Integer> list = new ArrayList<>();
for (int i=0; i < len; i++) {
//循环获取层序中的值(pollFirst)
Node node = que.pollFirst();
list.add(node.val);
//获取孩子节点数组,循环加入数组
List<Node> child = node.children;
for (Node n: child) {
que.offerLast(n);
}
}
res.add(list);
}
return res;
}
}
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II
104.二叉树的最大深度
111.二叉树的最小深度
226.翻转二叉树
解题思路:
-
递归方式 前序、后序递归都可以翻转二叉树
-
把每个节点的左右孩子翻转一下就可以
Java代码
/**
* 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 root;
}
//后序遍历-翻转二叉树
/**
1. 节点4进入
2. 4.left=2进行递归,
2.left=1进行递归,
1.left=null进行递归,root=null退出,程序往下走;
1.right=null进行递归,root=null退出,程序往下走;
交换1的左右孩子,1递归完成,回归到2.right
2.right=3进行递归
3.left=null进行递归,root=null退出,程序往下走;
3.right=null进行递归,root=null退出,程序往下走;
交换3的左右孩子,3递归完成,回归到交换2的左右孩子
交换2的左右孩子,程序走完回归到4.right
3. 4.right=7进行递归,
7.left=6进行递归,
6.left=null进行递归,root=null退出,程序往下走;
6.right=null进行递归,root=null推出,程序往下走;
交换6的左右孩子,6递归完成,回归到7.right
7.right=9进行递归,
9.left=null进行递归,root=null退出,程序往下走;
9.right=null进行递归,root=null退出,程序往下走;
交换9的左右孩子,9递归完成,回归到交换7的左右孩子
交换7的左右孩子,7递归完成,回归到交换4的左右孩子
4. 交换4的左右孩子,递归完成
*/
invertTree(root.left);
invertTree(root.right);
swapChildren(root);
return root;
}
private void swapChildren(TreeNode root) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
}
101.对称二叉树
解题思路:
-
注意对称二叉树不是比较左右孩子,而是比较根节点的左子树和右子树是不是相互翻转的
Java代码
/**
* 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) {
//1.确认返回值和传入参数(比较左右子树是否互相翻转简化为比较左右子树的外侧和内侧是否一致,返回类型是布尔类型)
//2.终止条件
/**
1. 左节点=null&&右节点!=null return false;
2. 左节点!=null&&🈶️节点=null return false;
3. 左右节点都为null return true;
4. 左右节点val不同 return false;
5. 左右节点val相同 单层逻辑
*/
//3,单层逻辑
/**
1. 左节点的左孩子 比较右节点的右孩子
2. 左节点的右孩子 比较右节点的做孩子
3. 上面两个都相同,return true
*/
if (root == null) {
return true;
}
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 same1 = compare(left.left, right.right);
boolean same2 = compare(left.right, right.left);
boolean isSame = same1 && same2;
return isSame;
}
}