给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
思考
对称二叉树,其实可以转化为根节点的左子树A是否和其右子树B对称。
如何判断是否对称,可以翻转左子树A,然后同时层次遍历A和B子树(如果某个节点只有一个子树,另一个子树需要记为null)。
大致步骤
- 获取根节点的左右子树left,right
- 翻转left
- 将left和right各个节点的值和各个节点的左右子树为null加入集合leftList,rightList
- 判断集合是否相等
package 力扣;
import sun.applet.Main;
import sun.plugin.javascript.navig.LinkArray;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
* @author yyq
* @create 2022-04-08 9:26
*/
public class leetcode101 {
public static void main(String[] args) {
TreeNode root=new TreeNode(1);
root.left=new TreeNode(2);
root.left.right=new TreeNode(3);
root.right=new TreeNode(2);
root.right.right=new TreeNode(3);
System.out.println(isSymmetric(root));
}
public static boolean isSymmetric(TreeNode root) {
if(root==null) return false;
if(root.left==null&&root.right==null)return true;
TreeNode left = root.left;
TreeNode right = root.right;
ArrayList<Integer> leftList=new ArrayList<>();
ArrayList<Integer> rightList=new ArrayList<>();
invertTree(left);
preOrder(left,leftList);
preOrder(right,rightList);
if(leftList.equals(rightList)) return true;
else return false;
}
public static TreeNode invertTree(TreeNode root) {
if(root==null) return root;
preOrderInvert(root);
return root;
}
private static void preOrderInvert(TreeNode root) {
if(root==null) return;
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
if(root.left!=null) preOrderInvert(root.left);
if(root.right!=null) preOrderInvert(root.right);
}
static void preOrder(TreeNode root,ArrayList<Integer> list){
if(root==null) return;
list.add(root.val);
if(root.left!=null) preOrder(root.left,list);
else list.add(null);
if(root.right!=null) preOrder(root.right,list);
else list.add(null);
}
}
唯一遗憾的是效率太低了
我觉得如果在遍历过程中直接进行比较可以大幅度提高效率,如果不相同根本不用遍历完子树。
实现后的效果果然如我所料,其实变成了两个二叉树是否相同的问题。我最开始的想法虽然也可以,但是效率不行,可以边遍历边比较的。
步骤
- 获取根节点的左右子树left,right
- 翻转left
- 进行前序遍历,比较两个子树left和right是否相同
class Solution {
public static boolean isSymmetric(TreeNode root) {
if(root==null) return false;
if(root.left==null&&root.right==null)return true;
TreeNode left = root.left;
TreeNode right = root.right;
if(left==null&&right!=null) return false;
if(right==null&&left!=null) return false;
int[] flag=new int[1];
flag[0] = 1;
invertTree(left);
preOrderadvanced(left,right,flag);
if(flag[0] == 1)return true;
else return false;
}
// 翻转二叉树
public static TreeNode invertTree(TreeNode root) {
if(root==null) return root;
preOrderInvert(root);
return root;
}
private static void preOrderInvert(TreeNode root) {
if(root==null) return;
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
if(root.left!=null) preOrderInvert(root.left);
if(root.right!=null) preOrderInvert(root.right);
}
// 比较两个子树是否相同
static void preOrderadvanced(TreeNode left,TreeNode right,int[] flag){
if(left.val!=right.val) {
flag[0] =0;
return;
}
if(left.left!=null&&right.left!=null){
preOrderadvanced(left.left,right.left,flag);
}else {
if(left.left ==null){
if(right.left!=null) {
flag[0] = 0;
return;
}
}
if(right.left == null){
if(left.left!=null) {
flag[0] = 0;
return;
}
}
}
if(left.right!=null&&right.right!=null){
preOrderadvanced(left.right,right.right,flag);
}else {
if(left.right ==null){
if(right.right!=null) {
flag[0] = 0;
return;
}
}
if(right.right == null){
if(left.right!=null) {
flag[0] = 0;
return;
}
}
}
}
}