leetcode.101.Symmetric Tree

Description

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

sln1

通過深度優先搜索去遍歷一棵樹,有三種可選的順序,分別是前序,中序和後序。這裏的前中後是指要在什麼時候算上父節點,是遍歷子節點前,還是兩個節點之間還是遍歷完子節點之後?在這裏我們隨便選擇一種遍歷順序,我選擇了後序遍歷。在後續遍歷中,如果我對每個節點都是先遍歷左子節點的話,最終會得到一種樹節點的列表順序。而如果我先遍歷右子節點的話,又會得到一種樹節點的列表順序。如果這兩個順序是相等的,說明這個樹是對稱的。實現代碼如下:

# 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
        """
        return root is None or (self.leftFirst(root) == self.rightFirst(root))

    def leftFirst(self, root):
        if root is None:
            return [None]
        nodes = []
        nodes.extend(self.leftFirst(root.left))
        nodes.extend(self.leftFirst(root.right))
        nodes.append(root.val)
        return nodes
    def rightFirst(self, root):
        if root is None:
            return [None]
        nodes = []
        nodes.extend(self.rightFirst(root.right))
        nodes.extend(self.rightFirst(root.left))
        nodes.append(root.val)
        return nodes

sln2

在sln1的提交結果分析中,發現這種深度優先搜索的方法僅僅超過了10%+的python結果,說明還有很大的優化空間。不難發現,在sln1中,如果樹是不對稱的,我們還是會把整棵樹遍歷完之後纔會發現,而且是遍歷兩遍。但如果一顆不對稱的樹很深,而且在靠近葉子節點的地方就出現不對稱的情況了,這樣我們其實是能夠更早就發現的。所以我們要想一種方法,能夠實現當樹一旦出現不對稱的情況,我們就不再做無效的計算。
通過參考Discuss中大牛們的解法,看到一種十分易於理解且高效的實現,思路如下:如果一棵樹是對稱的,那麼他的左子樹和右子樹應該互爲鏡像。那麼怎麼判斷左子樹和右子樹互爲鏡像呢,首先是左子樹和右子樹的根節點要相等。其次是左子樹的左子樹要和右子樹的右子樹互爲鏡像(isMirror(root.left.left, root.right.right))同時左子樹的右子樹和右子樹的左子樹要互爲鏡像(isMirror(root.left.right, root.right.left))。那麼,一旦某個子節點不是對稱的,他就會返回給上面的父節點。上面的父節點知道下面已經有不對稱的子樹了,自己已經不可能對稱了,就會不斷把這個消息上傳,至到樹的根節點。所以避免掉了許多無效的操作。利用這種算法,我們成功超過了95%+的python程序。算法實現如下:

# 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
        """
        return root is None or self.isMirror(root.left, root.right)

    def isMirror(self, nodeA, nodeB):
        if nodeA is None and nodeB is None:
            return True
        if nodeA is None or nodeB is None:
            return False
        return (nodeA.val == nodeB.val) and self.isMirror(nodeA.left, nodeB.right) and self.isMirror(nodeA.right, nodeB.left)
發佈了28 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章