代码随想录Day 15 - 二叉树
102. 二叉树的层序遍历
层序遍历的非递归写法与前序遍历/后序遍历的非递归写法有很大的相似之处,只不过把栈换成了队列。由于返回的是二维数组,在每次判断队列非空的时候,还会创建一个一维数组来存放一层的节点,len用来标记每一层的节点个数。
下面给出层序遍历的递归法和迭代法的代码:
递归法
//递归
class Solution {
public List<List<Integer>> list = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
level(root,0);
return list;
}
public void level(TreeNode node, int deep){
if(node == null) return;
deep++;
//通过二维数组的下标来判断层数
if(list.size() < deep){
List<Integer> item = new ArrayList<>();
list.add(item);
}
list.get(deep - 1).add(node.val);
level(node.left, deep);
level(node.right, deep);
}
}
迭代法
//用队列实现
class Solution {
public List<List<Integer>> list = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
level(root);
return list;
}
public void level(TreeNode root){
if(root == null) return;
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
while(!que.isEmpty()){
//每一层都需要用一个新的List来存放
List<Integer> item = new ArrayList<>();
//len用来标记每一层的节点个数
int len = que.size();
while(len > 0){
TreeNode node = que.poll();
item.add(node.val);
if(node.left != null){
que.offer(node.left);
}
if(node.right != null){
que.offer(node.right);
}
len--;
}
list.add(item);
}
}
}
226.翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
本题的迭代法的解法可以基于层序遍历的模板,当然也可以基于前序/后续遍历
递归法(前序遍历)
//递归法
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 node){
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
}
迭代法(层序遍历的模板)
//迭代法(层序遍历的模板)
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return null;
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
while(!deque.isEmpty()){
int len = deque.size();
while(len > 0){
TreeNode node = deque.poll();
swap(node); //中
if(node.left != null){
deque.offer(node.left); //左
}
if(node.right != null){
deque.offer(node.right); //右
}
len--;
}
}
return root;
}
public void swap(TreeNode node){
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
}
101. 对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。
注意递归的参数和返回条件,这里参数需要有两个节点。
递归法(后序遍历)
//递归法
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left, root.right);
}
public boolean compare(TreeNode left, TreeNode right){
if(left == null && right == null){
return true;
}else if(left == null && right != null){
return false;
}else if(left != null && right == null){
return false;
}else if(left.val != right.val){
return false;
}
Boolean outside = compare(left.left, right.right); //左
Boolean inside = compare(left.right, right.left); //右
return outside && inside; //中
}
}
迭代法
//迭代法
class Solution {
public boolean isSymmetric(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root.left);
deque.offer(root.right);
while(!deque.isEmpty()){
TreeNode left = deque.poll();
TreeNode right = deque.poll();
//注意判断左右为空返回continue需要放在最前面,否则left.val可能会报错误
if(left == null && right == null){
continue;
}
if(left != null && right == null){
return false;
}
if(left == null && right != null){
return false;
}
if(left.val != right.val){
return false;
}
deque.offer(left.left);
deque.offer(right.right);
deque.offer(left.right);
deque.offer(right.left);
}
return true;
}
}