leetcode 101. Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

    1
   / \
  2   2
 / \ / \
3  4 4  3

But the following [1,2,2,null,3,null,3] is not:

    1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.

先看迭代解法,就是先序遍历,不过顺序是左子树按照root->left->right顺序,右子树按照root->right->left顺序比较每次遍历的节点是否相等。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # use preorder to traverse root.left and root.right
        if not root: return True        
        stack1, stack2 = [root.left], [root.right]
        while stack1 and stack2:
            n1, n2 = stack1.pop(), stack2.pop()
            if n1 and n2 and n1.val == n2.val:
                if n1.right and n2.left: 
                    stack1.append(n1.right)
                    stack2.append(n2.left)
                elif n1.right or n2.left:
                    return False
                if n1.left and n2.right: 
                    stack1.append(n1.left)
                    stack2.append(n2.right)
                elif n1.left or n2.right:
                    return False
            elif n1 or n2:
                return False
        return len(stack1)==0 and len(stack2)==0

优化下:

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # use preorder to traverse root.left and root.right
        if not root: return True       
        stack1, stack2 = [root.left], [root.right]
        while stack1 and stack2:
            n1, n2 = stack1.pop(), stack2.pop()
            if not n1 and not n2: continue
            if (n1 and not n2) or (n2 and not n1): return False
            if n1.val != n2.val: return False
            stack1.append(n1.right)
            stack2.append(n2.left)
            stack1.append(n1.left)
            stack2.append(n2.right)
        return len(stack1)==0 and len(stack2)==0

 

递归解法:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # use preorder to traverse root.left and root.right
        if not root: return True        
        
        def is_equal(l, r):
            if l and r:
                if l.val != r.val: return False
                return is_equal(l.left, r.right) and is_equal(l.right, r.left)
            else:
                return l == r
        
        return is_equal(root.left, root.right)

BFS:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # use preorder to traverse root.left and root.right
        if not root or root.left == root.right: return True      
        
        def is_one_null(n1, n2):
            return (n1 and not n2) or (not n1 and n2)
        
        if is_one_null(root.left, root.right): return False
        
        q = [root.left, root.right]
        while q:
            leng = len(q)
            for i in xrange(0, leng/2):
                l, r = q[i], q[leng-1-i]
                if l.val == r.val:
                    if is_one_null(l.left, r.right) or is_one_null(l.right, r.left):
                        return False                    
                else:
                    return False
            q = [node for n in q for node in (n.left, n.right) if node]
        return True        

或者是将两个待比较的节点放在一起入队和出队。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # use preorder to traverse root.left and root.right
        if not root: return True      
        
        def is_one_null(n1, n2):
            return (n1 and not n2) or (not n1 and n2)
        
        q = collections.deque([root.left, root.right])
        while q:
            n1, n2 = q.popleft(), q.popleft()
            if not n1 and not n2: continue
            if is_one_null(n1, n2): return False
            if n1.val != n2.val: return False
            q.append(n1.left)
            q.append(n2.right)
            q.append(n1.right)
            q.append(n2.left)
        return True
        

 黄色部分可以简化下代码。避免冗余的if判断!

再度优化下之前的stack 迭代代码:

 class Solution2:
  def isSymmetric(self, root):
    if root is None:
      return True

    stack = [[root.left, root.right]]

    while len(stack) > 0:
      pair = stack.pop(0)
      left = pair[0]
      right = pair[1]

      if left is None and right is None:
        continue
      if left is None or right is None:
        return False
      if left.val == right.val:
        stack.insert(0, [left.left, right.right])

        stack.insert(0, [left.right, right.left])
      else:
        return False
    return True

 

这种题目就是考察是否细心。

public boolean isSymmetric(TreeNode root) {
    return root==null || isSymmetricHelp(root.left, root.right);
}

private boolean isSymmetricHelp(TreeNode left, TreeNode right){
    if(left==null || right==null)
        return left==right;
    if(left.val!=right.val)
        return false;
    return isSymmetricHelp(left.left, right.right) && isSymmetricHelp(left.right, right.left);
}

 黄色部分等价于:

    if(p==null && q==null) return true; if(p==null || q==null) return false;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值