面试题18:树的子结构

树的子结构

这道题需要注意的是,怎么才能称作是树的子结构,是允许一部分相同,还是说必须到叶结点也要相等?如果是前者,则不需要判断双方当前是否已经到达了叶结点,而后者是需要的。

不需要到叶结点

class Solution(object):
    def recursive(self, s, t):
        if t is None:
            return True
        if s is None:
            return False
        if s.val != t.val:
            return False
        return self.recursive(s.left, t.left) and self.recursive(s.right, t.right)
    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
        res = False
        if s is not None and t is not None:
            if s.val == t.val:
                res = self.recursive(s, t)
            if not res:
                res = self.isSubtree(s.left, t)
            if not res:
                res = self.isSubtree(s.right, t)
        return res

需要到叶结点

DFS

class Solution(object):
    def recursive(self, s, t):
        if s is None and t is None:
            return True
        else:
            if t is None or s is None:
                return False
        if s.val != t.val:
            return False
        return self.recursive(s.left, t.left) and self.recursive(s.right, t.right)
    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
        res = False
        if s is not None and t is not None:
            if s.val == t.val:
                res = self.recursive(s, t)
            if not res:
                res = self.isSubtree(s.left, t)
            if not res:
                res = self.isSubtree(s.right, t)
        return res

优化-统计每个结点的子结点个数

class Solution(object):
    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
        def makeTag(root):
            if not root:
                return 0
            left = makeTag(root.left)
            right = makeTag(root.right)
            self.tag[root] = left+right +1
            return left+right +1
        self.tag = {}
        makeTag(s)
        makeTag(t)
        return self.isSubtree2(s,t)
    def isSubtree2(self,s,t):
        if not s:
            return False
        if self.isSame(s,t):
            return True
        return self.isSubtree2(s.left,t) or self.isSubtree2(s.right,t)
    def isSame(self, s,t):
        if not s and not t:
            return True
        elif not s or not t:
            return False
        if self.tag[s] != self.tag[t]:
            return False
        return s.val == t.val and self.isSame(s.left,t.left) and self.isSame(s.right,t.right) 

优化-统计每一个结点的高度

def _set_heights(root):
    if not root:
        return 0
    lh = _set_heights(root.left)
    rh = _set_heights(root.right)
    root.height = max(lh, rh) + 1
    return root.height
def _match(s, t):
    if not s or not t:
        return s is t
    if s.height < t.height:
        return False
    if s.height > t.height:
        return _match(s.left, t) or _match(s.right, t)
    return s.val == t.val and _match(s.left, t.left) and _match(s.right, t.right)
class Solution(object):
    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
        if not s or not t:
            return s is t
        _set_heights(s)
        _set_heights(t)
        return _match(s, t)

字符串比较

将树转化成固定格式的字符串表达形式,再进行判断

class Solution(object):
    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
        def convert(p):
            return '~' + str(p.val) + '$' + convert(p.left) + convert(p.right) if p else '&'
        return convert(t) in convert(s)

或者是将树中的结点的值组成字符串,然后再进行比较

class Solution(object):
    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
        preorder_s = self.preorderString(s)
        preorder_t = self.preorderString(t)
        print(preorder_s)
        return preorder_s.find(preorder_t) != -1
    def preorderString(self, tree):
        out = ""
        stack = [tree]
        while stack:
            curr = stack.pop()
            if curr:
                out = ",".join([out, str(curr.val)])
                stack.append(curr.left)
                stack.append(curr.right)
            else:
                out = out + "!"
        return out
posted @ 2017-08-07 16:11  banananana  阅读(197)  评论(0编辑  收藏  举报