目录
一、题目
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
限制:
0 <= 节点个数 <= 1000
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:输入:root = [1,2,2,null,3,null,3]
输出:false
二、递归写法
思路:若树的做左子树与右子树镜像对称、则此树对称。
判断两棵树镜像对称:
1、根结点具有相同的值。
2、左个树的右子树都与,右一个树的左子树镜像对称
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public boolean isSymmetric(TreeNode root) { // 特殊情况 if(root==null){ return true; } return isMirror(root.left, root.right); } public boolean isMirror(TreeNode left, TreeNode right) { if (left == null && right == null) { return true; } if (left == null || right == null) { return false; } return left.val == right.val && isMirror(left.left, right.right) && isMirror(left.right, right.left); } }
时间复杂度O(N),N为结点数。
空间复杂度O(N),N为数的层数。
执行结果
三、使用辅助队列
思路:
每次两个结点并比较它们的值(两个连续的结点应该是相等的,而且它们的子树互为镜像),然后将两个结点的左右子结点按相反的顺序插入队列中。
class Solution { public boolean isSymmetric(TreeNode root) { // 特殊情况 if(root==null){ return true; } Queue<TreeNode> queue = new LinkedList<TreeNode>(); // 左右子树入队 queue.offer(root.left); queue.offer(root.right); while (!queue.isEmpty()) { // 先入先出 TreeNode left = queue.poll(); TreeNode right = queue.poll(); if (left == null && right == null) { continue; } // 判断队列连续两个元素的值 if ((left == null || right == null) || (left.val != right.val)) { return false; } // 左右子树子节点相反顺序入队 queue.offer(left.left); queue.offer(right.right); queue.offer(left.right); queue.offer(right.left); } return true; } }
注意:
入队:add(e)、offer(e),插入失败前者会抛异常
出队:remove()、poll(),删除失败前者会抛异常
抛出:
ClassCastException – 如果指定元素的类阻止将其添加到此队列
NullPointerException – 如果指定的元素为null,并且此队列不允许null元素
IllegalArgumentException –如果此元素的某些属性阻止将其添加到此队列
执行结果
四、使用辅助栈
class Solution { public boolean isSymmetric(TreeNode root) { // 特殊情况 if(root==null){ return true; } Stack<TreeNode> stack = new Stack<>(); // 左右子树入栈 stack.push(root.left); stack.push(root.right); while (!stack.isEmpty()) { TreeNode right = stack.pop(); TreeNode left = stack.pop(); if (left == null && right == null){ continue; } // 判断连续连个元素的值 if (left == null || right == null || (left.val != right.val)) { return false; } // 左右子树的左右结点入栈 stack.push(left.left); stack.push(right.right); stack.push(right.left); stack.push(left.right); } return true; } }
执行结果