文档讲解:代码随想录(代码随想录)
完成状态: true
102. 二叉树的层序遍历
思路:
层序遍历很容易想到用队列来解决,队列是先进先出的,可以保存一层又一层的二叉树节点。直接输出层序遍历的顺序是比较简单的,比较难的是怎么想到对每一层进行单独的保存操作。
这里可以每次遍历之前保存队列当前的长度,此时其长度就是当前层的节点个数,有了这个长度ze记录当前层的元素个数后,既可以对这一层节点进行输出,同时遍历这一层节点后,就可以讲对应的下一层节点全部放入队列中,此时的节点个数也就是下次循环size记录的节点个数。
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(root == null){
return result;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> itemList = new ArrayList<Integer>();
int size = queue.size(); // 保存每一层的节点个数
while(size > 0){
TreeNode node = queue.poll();
itemList.add(node.val);
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
size--;
}
result.add(itemList);
}
return result;
}
}
226. 翻转二叉树
最开始只想到了后序遍历,但是进一步一想,前序遍历也是可以的。只不过前序遍历是从顶部到底部去反转二叉树,而后序遍历则是从底部到顶部去反转。
后序遍历:
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null){
return null;
}
invertTree(root.left); // 左
invertTree(root.right); // 右
// 根 反转二叉树
TreeNode temp = new TreeNode();
temp = root.left;
root.left = root.right;
root.right = temp;
return root;
}
}
中序遍历:
但是中序遍历是不可以的,因为中序遍历在第一次正常交换了左右节点后,回退到上一层,再一次交换左右节点后,由于是左根右,此时也正需递归遍历右子树了,此时由于已经交换过了,如果继续递归root.right,此时的右子树实际上是已经反转过的左子树。
所以实际上处理逻辑应该是左根左,最后的左实际是未交换前的右子数。
101. 对称二叉树
一开始拿到这个题思路是混乱的,我认为这道题还是有些难度的,因为之前并未遇到同时遍历两个二叉树的情况。
考虑这样的一个题目,有两个独立的二叉树,现在让你判断这两个二叉树是否完全一致。这就是要去同时遍历两个二叉树的情况。首先想清楚这是否是个递归问题?是的话用什么遍历顺序?
- 递归问题。假如两个独立的二叉树如下,首先判断两个二叉树整体是不是完全一致,此时根节点是左图的2和右图的2,也就是需要判断两个二叉树的左子树和右子树是否完全一致。这个时候就发现,两个二叉树的左子树(右子树)又是一个二叉树结构,此时变为判断他们以3为根节点的两个二叉树是否完全一致,也就是需要判断以3为根节点的左图的二叉树和右图的二叉树的左右子树是否完全一致。接下来...可以看到这就是一个标准的递归结构。
每一次都是去判断两个不同二叉树左右子树是否完全一致的过程。
- 后序遍历。本质是后序遍历的变体。需要我们收集左右孩子的信息后,并向上一层(根节点)返回的时候,这类题目是需要后序遍历的。
对称二叉树也就是左子树和右子树是可以互相反转的,反转任意一个二叉树,两个二叉树就是完全一致的。有了上述的引入,这道题就迎刃而解了。
第一次写完代码运行报错,如下所示。问题出在每次判断都去判断当前节点的左节点和右节点,但是若当前节点已经为空,则会产生空指针异常。还是对问题没有思考透彻。
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null){
return true;
}
return compare(root.left, root.right);
}
public boolean compare(TreeNode leftTreeRoot, TreeNode rightTreeRoot){
if(leftTreeRoot != null && rightTreeRoot == null){
return false;
}
if(leftTreeRoot == null && rightTreeRoot != null){
return false;
}
if(leftTreeRoot == null && rightTreeRoot == null){
return true;
}
if(leftTreeRoot.val != rightTreeRoot.val){ // 左右都不为空,但是数值不相等
return false;
}
// 后序遍历
boolean outSide = compare(leftTreeRoot.left, rightTreeRoot.right);
boolean inSide = compare(leftTreeRoot.right, rightTreeRoot.left);
boolean result = outSide && inSide;
return result;
}
}