二叉树的层序遍历
这里主要看了借助队列的方式
1.new一个新的队列
2.如果根结点不为空的话,将结点添加进队列中
3.当队列不为空时进入循环
首先设置变量记录当前队列的size,此处记录了每层的元素个数,也决定了下一个循环循环几次,当size>0时记录将这一层的每个结点值添加进list中,将这一层节点的左右结点添加进队列。
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
List<List<Integer>> list = new ArrayList<>();
if(root==null){return list;}
while(!q.isEmpty()){
int size = q.size();
List<Integer> list1 = new ArrayList<>();
while(size>0){
TreeNode tn = q.poll();
list1.add(tn.val);
if(tn.left!=null){
q.offer(tn.left);
}
if(tn.right!=null){
q.offer(tn.right);
}
size--;
}
list.add(list1);
}
return list;
}
}
102. 二叉树的层序遍历 在进入下一层循环之前,new一个list,最后将这个list添加进结果list中
107. 二叉树的层序遍历 II 相对于102.二叉树的层序遍历,就是最后把result数组反转一下就可以了。
199. 二叉树的右视图 遍历每一层,但是在list中只添加每一层的最后一个元素
637. 二叉树的层平均值 给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。
515. 在每个树行中找最大值 层序遍历,取每一层的最大值
116.填充每个节点的下一个右侧节点指针 (小绕)
本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了,先poll()一个作为第一个结点,再进入for循环poll()出第二个结点,让第一个结点的next指向下一个结点。
117. 填充每个节点的下一个右侧节点指针 II - 力扣(LeetCode)同116仅在题目描述上有区别,答案相同
104. 二叉树的最大深度 定义一个depth变量,每次进入新的一层都++
111. 二叉树的最小深度定义一个depth变量,每次进入新的一层都++,但是上面一题是结束循环之后返回depth,此处是如果遇到一个节点的左子节点和右子节点都为空就返回,因为此时就是它的最小深度。
226.翻转二叉树
初始思路&&题解复盘:
利用递归来解决问题,输入当前节点,然后交换左右节点,此处利用递归,
交换左子节点的左右节点,交换右子节点的左右节点。
递归三部曲:
1.确定递归函数的参数和返回值
参数就是要传入节点的指针,返回值的话其实也不需要,但是题目中给出的要返回root节点的指针,可以直接使用题目定义好的函数,所以就函数的返回类型为TreeNode*
。
2.确定终止条件
当前节点为空的时候,就返回
3.确定单层递归的逻辑
因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。
迭代法大致思路,每次while循环中:交换根节点的左右节点然后push右节点入栈push左节点入栈
层序遍历:进入每层也是交换根节点左右节点然后将其左右子节点offer进入队列
注意迭代的中序:
因为先交换左节点的左右节点,在交
换根节点的左右节点,再交换右节点(此时交换的右节点就是原来的左子节点所以代码应该这么写
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == NULL) return root;
invertTree(root->left); // 左
swap(root->left, root->right); // 中
invertTree(root->left); // 注意 这里依然要遍历左孩子,因为中间节点已经翻转了
return root;
}
};
101. 对称二叉树
初始思路&&题解复盘:
一定要使用后序遍历!!只有确定了其左子树和右子树对称,才能确定这个根节点和另一个根节点是对称的
递归三部曲
- 确定递归函数的参数和返回值
因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。
返回值自然是bool类型。
2.确定终止条件
节点为空的情况有:(注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点)
- 左节点为空,右节点不为空,不对称,return false
- 左不为空,右为空,不对称 return false
- 左右都为空,对称,返回true
此时已经排除掉了节点为空的情况,那么剩下的就是左右节点不为空:
- 左右都不为空,比较节点数值,不相同就return false
3.确定单层递归的逻辑此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。
- 比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
- 比较内侧是否对称,传入左节点的右孩子,右节点的左孩子。
- 如果左右都对称就返回true ,有一侧不对称就返回false
/** * 递归法 */ public boolean isSymmetric1(TreeNode root) { return compare(root.left, root.right); } private boolean compare(TreeNode left, TreeNode right) { if (left == null && right != null) { return false; } if (left != null && right == null) { return false; } if (left == null && right == null) { return true; } if (left.val != right.val) { return false; } // 比较外侧 boolean compareOutside = compare(left.left, right.right); // 比较内侧 boolean compareInside = compare(left.right, right.left); return compareOutside && compareInside; }