层序遍历(即广度优先搜索)
需要借用一个队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
思路是先把根节点加入队列,然后在遍历下一层前,先将队列拥有的当前层元素加入到结果集中,然后再将当前节点的左节点,右节点加入到队列中
class Solution {
List<List<Integer>> resList=new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
checkFun(root);
return resList;
}
//BFS--迭代方式--借助队列
public void checkFun(TreeNode node){
if(node==null){return;}
Queue<TreeNode> que=new LinkedList<TreeNode>();//借助辅助队列
que.offer(node);//向队尾插入元素
while(!que.isEmpty()){
List<Integer> itemList=new ArrayList<Integer>();
int len=que.size();
while(len>0){//这里不能是 while(!que.isEmpty()),因为如果是那样子,那么外层while循环就不执行了
TreeNode tmpNode=que.poll();//拿出队头元素
itemList.add(tmpNode.val);
if(tmpNode.left!=null){que.offer(tmpNode.left);}
if(tmpNode.right!=null){que.offer(tmpNode.right);}
len--;
}
resList.add(itemList);
}
}
}
226.翻转二叉树
226. 翻转二叉树
解法一BFS
思路:先将根节点添加到队列中,队列不为空,则计算出队列的长度size,如果size大于0则一直反转当前遍历到的节点的左右树
//BFS
class Solution {
public TreeNode invertTree(TreeNode root) {
//层序遍历吧
if(root==null){return null;}
Deque<TreeNode> deque=new ArrayDeque<>();
deque.offer(root);//插入元素到队尾
while(!deque.isEmpty()){
int size=deque.size();
while(size-->0){
TreeNode node=deque.poll();//移除队头元素
swap(node);
if(node.left!=null){deque.offer(node.left);}
if(node.right!=null){deque.offer(node.right);}
}
}
return root;
}
public void swap(TreeNode root){
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
}
}
解法二DFS
思路:就是这里注意中序遍历是无法达到反转的要求的,不信可以自己举个例子
采用后序遍历,首先递归将左子树和右子树翻转,最后翻转根节点
//DFS递归
class Solution {
/**
* 前后序遍历都可以
* 中序不行,因为先左孩子交换孩子,再根交换孩子(做完后,右孩子已经变成了原来的左孩子),再右孩子交换孩子(此时其实是对原来的左孩子做交换)
*/
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
invertTree(root.left);
invertTree(root.right);
swapChildren(root);
return root;
}
private void swapChildren(TreeNode root) {
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
}
}
101. 对称二叉树
注意我们比较的其实不是左孩子和右孩子,所以如下我称之为左节点右节点
思路
比较左节点的外侧和右节点的外侧,比较左节点的里侧和右节点的里侧
考虑五种情况
节点为空的情况有:(这是终止条件)
- 左节点为空,右节点不为空,不对称,return false
- 左不为空,右为空,不对称 return false
- 左右都为空,对称,返回true
- 左右节点不为空,且数值也不相同的情况我们也处理了
- 第五种情况是都不为空且数值相等
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left,root.right);
}
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!=null&&right!=null&&left.val!=right.val){return false;}
//第五种情况就是非空且数值相同的情况
//单层递归逻辑
boolean b1=compare(left.left,right.right);
boolean b2=compare(left.right,right.left);
return b1&&b2;
}
}