• 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;
  • 相关阅读:
    Win10关闭自动更新
    NGUI(三) 下拉框(弹出列表)PopupList、单选框Checkbox
    NGUI(二) widget,Anchor锚点,Tween补间动画,Slider滑动器,滑动条变色,打字机TypewriterEffect
    NGUI(一) UIROOT,Label,Sprite,Button,Panel,创建字体,创建图集,按钮添加点击音效
    NGUI脚本
    c#常用类库
    Application位置
    常用单词
    Proto在C++的使用
    Protobuf语法
  • 原文地址:https://www.cnblogs.com/bonelee/p/8875432.html
Copyright © 2020-2023  润新知