102.二叉树的层序遍历
给你二叉树的根节点
root,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
- 树中节点数目在范围
[0, 2000]内-1000 <= Node.val <= 1000
思路
- 若
root为空,即节点数量为0,返回空数组。 - 否则,使用队列对二叉树进行遍历。将
root入队,将null作为每一层的分隔符入队。- 当队列中元素数量大于 2 时,进行循环
- 在每一轮循环中,创建一个列表
list,- 从队列中出队一个元素,
- 若该元素不是
null,则将该元素的数值加入到list中 - 依次判断该元素是否有左、右孩子,若有,则加入队列中;
- 若该元素是
null,则将list加入到结果中,在队列中插入一个分隔符null。 - 结束本轮循环。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null){
return res;
}
Deque<TreeNode> que = new LinkedList<>();
TreeNode cur = null;
que.add(root);
que.add(null);
do{
List<Integer> list = new ArrayList<>();
while((cur = que.poll()) != null){
list.add(cur.val);
if(cur.left != null){
que.add(cur.left);
}
if(cur.right != null){
que.add(cur.right);
}
}
res.add(list);
que.add(null);
}while(que.size()>1);
return res;
}
}
226.翻转二叉树
给你一棵二叉树的根节点
root,翻转这棵二叉树,并返回其根节点。
思路
使用二叉树深度遍历的任一种方法,当遍历到任一节点时,将具体操作替换成交换该节点的左右孩子节点。
交换节点的左右孩子节点时,只要该节点存在左孩子或右孩子,都可以进行交换,将 null也作为孩子进行交换可减少代码量。
使用二叉树广度遍历时,不需要区分每一层的元素,因此使用一个for循环即可,当队列为空时结束循环。
代码
深度遍历的代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
invert(root);
return root;
}
private void invert(TreeNode cur){
if(cur == null){
return;
}
if(cur.left != null){
invert(cur.left);
}
if(cur.right !=null){
invert(cur.right);
}
swapChildren(cur);
}
private void swapChildren(TreeNode root){
if(root.left != null || root.right != null){
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
}
}
}
广度遍历的代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
Deque<TreeNode> que = new LinkedList<>();
if(root == null){
return root;
}
TreeNode cur = null;
que.add(root);
while(!que.isEmpty()){
cur = que.poll();
if(cur.left != null){
que.add(cur.left);
}
if(cur.right != null){
que.add(cur.right);
}
swapChildren(cur);
}
return root;
}
private void swapChildren(TreeNode root){
if(root.left != null || root.right != null){
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
}
}
}
101. 对称二叉树
给你一个二叉树的根节点
root, 检查它是否轴对称
- 树中节点数目在范围
[1, 1000]内
思路
对二叉树进行层序遍历。
- 判断根节点的情况
- 如果根节点同时没有左右孩子节点,即二叉树只有根节点这一个节点,则该二叉树是对称的,返回
true。 - 否则,如果根节点没有左孩子或没有右孩子,(由于根节点同时没有左右孩子节点为假,即根节点不能同时没有左右孩子节点),则二叉树是不对称的,返回
false。 - 否则,该二叉树的根节点同时拥有左右孩子,继续以下操作。
- 如果根节点同时没有左右孩子节点,即二叉树只有根节点这一个节点,则该二叉树是对称的,返回
- 将根节点的左右孩子节点依次加入队列中,当队列不为空时,对二叉树的每一层进行循环。
- 在一个循环中,先判断当前队列的
size是否是双数,如果不是,返回false,这个操作可以确保之后出队时可以一次性出队2个元素,避免代码出错;而同样地,不满足这个特性的二叉树是不对称的。 - 在队列中插入一个
null,作为当前层与下一层之间的分隔符。 - 进入循环,直到当前队列的队首元素为分隔符
null为止,在一次循环中,- 依次出队两个元素
fisrt和second, - 如果
fisrt和second的val不相等,即这两个对称位置的元素不相同,二叉树不对称,返回false; - 否则,判断
fisrt和second的孩子是否对称,包括外侧对称和内侧对称。 - 外侧对称的节点是
first.left和second.right,若这两个节点存在且值相等,将这两个节点入队;若这两个节点存在但值不相等,则不对称,返回false。 - 内侧对称的节点是
first.right和second.left,若这两个节点存在且值相等,将这两个节点入队;若这两个节点存在但值不相等,则不对称,返回false。 - 这样的操作后,可以看到,对称位置的节点在队列中是相邻的,因此每次出队的
fisrt和second是对称位置的元素。
- 依次出队两个元素
- 本轮循环结束,去除分隔符。这一步一定要做,否则影响循环判断条件的结果和之后程序的运行。
- 在一个循环中,先判断当前队列的
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root.left == null && root.right == null){
return true;
}else if(root.left == null || root.right == null){
return false;
}
Deque<TreeNode> que = new LinkedList<>();
que.add(root.left);
que.add(root.right);
TreeNode first = null, second = null;
do{
if(que.size()%2 != 0){
return false;
}
// 加入分隔符
que.add(null);
while(que.peek()!=null){
first = que.poll();
second = que.poll();
if(first.val!=second.val){
return false;
}
// 外侧
if(first.left != null && second.right != null){
if(first.left.val == second.right.val){
// 对称 且 非null
que.add(first.left);
que.add(second.right);
}else{
// 不对称 且 非null
return false;
}
}else if(first.left != null || second.right != null){
// 有一个为null ,而另一个不为 null
return false;
}
// 内侧
if(first.right != null && second.left !=null){
if(first.right.val == second.left.val){
// 对称 且 非null
que.add(first.right);
que.add(second.left);
}else{
return false;
}
}else if(first.right !=null || second.left !=null){
return false;
}
}
// 去除分隔符
que.poll();
}while(!que.isEmpty());
return true;
}
}