二叉树的层序遍历(这个顶满, 周末直接继续爆刷五题)
思路: 遍历每一层的节点, 利用一个队列保存, 利用len计算每一层长度, 如果长度为0, 说明这一层结束了, 就把这一层的数放在一个数组里, 最后有k层数组, 直接丢到二维数组里就行了
- 需要一个二维数组返回最终结果, 需要一个队列遍历每个节点, 还要一个数组获得每一层
- 首先用于都要判断root == null;
- 然后第一步肯定是把根节点放进队列, 也就是第一层
- 然后创建while循环, 条件是que不为空
- 循环里, 定义len, 统计每一层的长度
- 然后开始定义数组, 获得每一层的元素
- 创建内循环, 获得每一层, 之后和一般的迭代一样
- 内循环里面, 首先把每一层poll出来, 然后加到数组, 每次搞完len--
细节:
1. 外面的while是用来获得所有层数的数组, 里面的while是获得每一层的数组
2. 队列获取大小是用size方法
3. 这里是BFS, 所以每次孩子不为空的话就直接放到队列里了, 之前的DFS, 不为空就还要往下走
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//创建一个二位数组和队列(别忘记队列里放的是TreeNode)
List<List<Integer>> res = new ArrayList<>();
Queue<TreeNode> que = new LinkedList<>();
if(root == null){
return res;
}
//直接开始第一层, 也就是把根节点放到队列
que.offer(root);
while(!que.isEmpty()){
//定义长度, 放在这里是因为只有每一层的才不同
int len = que.size();
//定义数组收集每一层
List<Integer> list = new ArrayList<>();
//正式开始遍历每一层, 判断len
while(len > 0){
TreeNode cur = que.poll();
//把poll出来的元素放到list数组
list.add(cur.val);
if(cur.left != null){
que.offer(cur.left);
}
if(cur.right != null){
que.offer(cur.right);
}
//每次循环一个数,len都要--
len--;
}
res.add(list);
}
return res;
}
}
翻转二叉树
用前序和后序是最方便的
递归方法
- 确定返回值和参数: TreeNode invertTree(root)
- 确定终止条件: if(root == null), return null;
- 逻辑就是交换root的左右孩子
注意:
这里和遍历的代码还是不太一样的:
遍历是在前序遍历方法内递归, 然后solution方法里调用递归方法return
翻转是写一个翻转的方法, 然后solution方法内递归, 最后return
(这里只需要return一个root就行了)
前序:
class Solution {
public TreeNode invertTree(TreeNode root) {
//base case
if(root == null){
return null;
}
//中左右
swap(root);
invertTree(root.left);
invertTree(root.right);
return root;
}
void swap(TreeNode root){
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
}
后序:
class Solution {
public TreeNode invertTree(TreeNode root) {
//base case
if(root == null){
return null;
}
//中左右
swap(root);
invertTree(root.left);
invertTree(root.right);
return root;
}
void swap(TreeNode root){
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
}
层序遍历方法
也是用一个队列遍历每一层的元素, 也要len--, 唯一的区别就是每次队列poll出来的元素要swap
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null){
return null;
}
ArrayDeque<TreeNode> deque = new ArrayDeque<>();
deque.offer(root);
while(!deque.isEmpty()){
int size = deque.size();
while(size-- > 0){
TreeNode cur = deque.poll();
swap(cur);
if(cur.left != null){
deque.offer(cur.left);
}
if(cur.right != null){
deque.offer(cur.right);
}
}
}
return root;
}
public void swap(TreeNode root){
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
}
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 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);
boolean result = compareOutside && compareInside;
return result;
}
}
对称二叉树(用后序)
传入左子树和右子树
如果左为空, 右不空
如果左不空, 右为空
如果左右不为空, 但是值不相等
以上四种情况直接return false
如果左右都为空, 就return ture
如果值相等, 则向下一层遍历
比较外侧: left.left, right.right
比较内测: left.right, right.left
最后boolean result = outside & inside
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 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);
boolean result = compareOutside && compareInside;
return result;
}
}