代码随想录刷题Day15 | 102.二叉树的层序遍历 | 226.翻转二叉树 | 101.对称二叉树
102.二叉树的层序遍历
题目:
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
思路:
-
借助队列,首先将头节点入队,记录此时队列的长度,也就是该层的长度,然后逐个出队,并判断其是否有孩子,有的话入队。
-
递归实现
代码:
- 借助队列
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
Deque<TreeNode> queue = new LinkedList<>();
if(root == null) return result;
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
List<Integer> tmp = new LinkedList<>();
for(int i = 0; i < size; i++){
TreeNode tmpNode = queue.poll();
tmp.add(tmpNode.val);
if(tmpNode.left !=null) queue.add(tmpNode.left);
if(tmpNode.right != null) queue.add(tmpNode.right);
}
result.add(tmp);
}
return result;
}
}
- 递归
class Solution {
public List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
level(root, 0);
return result;
}
public void level(TreeNode root, int deep){
if(root == null) return;
deep++;
if(result.size() < deep){
List<Integer> tmp = new ArrayList<>();
result.add(tmp);
}
result.get(deep - 1).add(root.val);
level(root.left, deep);
level(root.right, deep);
}
}
226.翻转二叉树
题目:
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
思路:
注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果
这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次!
代码:
- 递归
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return null;
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
- 非递归
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return null;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode tmp = stack.pop();
swap(tmp);
if(tmp.right != null) stack.push(tmp.right);
if(tmp.left != null) stack.push(tmp.left);
}
return root;
}
public void swap(TreeNode root){
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
}
}
101.对称二叉树
题目:
给你一个二叉树的根节点 root
, 检查它是否轴对称。
思路:
首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点!
对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树),所以在递归遍历的过程中,也是要同时遍历两棵树。
本题遍历只能是“后序遍历”,因为我们要通过递归函数的返回值来判断两个子树的内侧节点和外侧节点是否相等。
正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。
代码:
class Solution {
public boolean isSymmetric(TreeNode root) {
return symmetric(root.left, root.right);
}
public boolean symmetric(TreeNode left, TreeNode right){
if(left == null && right == null) return true;
else if(left == null || right == null) return false;
else if(left.val != right.val) return false;
return symmetric(left.left, right.right) && symmetric(left.right, right.left);
}
}