树(5)-----判断两颗树一样或者一棵树是否是另外一颗的子树
1、判断两颗树是否一样。(递归)
def isSameTree(p,q): if not p and not q: return True elif not p and q or (not q and p): return False else: if p.val!=q.val: return False else: return isSameTree(p.left,q.left) and isSameTree(p.right,q.right)
2、判断一颗树是否为另外一颗的子树:【在判断是否一样树之上还加一层循环】(递归加循环)
def isSubtree(self, s, t): """ :type s: TreeNode :type t: TreeNode :rtype: bool """ def isSameTree(p,q): if not p and not q: return True elif not p and q or (not q and p): return False else: if p.val!=q.val: return False else: return isSameTree(p.left,q.left) and isSameTree(p.right,q.right) prev=[s] while prev: node=prev.pop() if node: if isSameTree(node,t): return True prev.extend([node.left,node.right])
法二:转化成字符串,判断字符串1是否在字符串2之中。
def isSubtree(s, t): def convert(tree): stack = [tree] string = '' while stack: node = stack.pop() if node: string += '#' + str(node.val) stack.extend((node.left, node.right)) else: string += '$' return string strings = convert(s) stringt = convert(t) return stringt in strings
3、寻找重复的子树
给定一棵二叉树,返回所有重复的子树。对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。
两棵树重复是指它们具有相同的结构以及相同的结点值。
示例 1:
1 / \ 2 3 / / \ 4 2 4 / 4
下面是两个重复的子树:
2 / 4
和
4
因此,你需要以列表的形式返回上述重复子树的根结点。
思路1:(先遍历所有的节点存在列表中,列表每个节点两两之间比较一下,是否是同一颗树,如果是就将该节点放入结果中,最后也要注意一下去重)【这个方法被我写得超出时间限制】
思路2:(先遍历所有的节点存在列表中,然后将每个节点对应的先序遍历存在另一个列表中,然后用一个字典存两个列表,先序遍历的列表作为key,节点列表作为value,若key有重复的,就将字典值加进结果,去重就可以了。)
from collections import defaultdict class Solution(object): def findDuplicateSubtrees(self, root): """ :type root: TreeNode :rtype: List[TreeNode] """ #思路1:超出时间限制 if not root: return [] listNode=[] def isSameTree(p,q): if not p and not q: return True elif (p and not q) or (q and not p): return False else: if p.val!=q.val: return False else: return isSameTree(p.left,q.left) and isSameTree(p.right,q.right) prev=[root] while prev: node=prev.pop(0) if node: listNode.append(node) prev.extend([node.left,node.right]) res=[] i=0 while i < len(listNode): j=i+1 flag=1 while i+1 <= j < len(listNode): if isSameTree(listNode[i],listNode[j]): if listNode[i] not in res: res.append(listNode[i]) del listNode[j] flag=0 if flag: j+=1 flag=1 i+=1 return res #思路2 if not root: return [] def order(root): orderRes=[] prev=[root] while prev: node=prev.pop() if node: orderRes.append(node.val) prev.extend([node.left,node.right]) else: orderRes.append(None) return orderRes prev=[root] dic=defaultdict(TreeNode) res=[] while prev: node=prev.pop() if node: if tuple(order(node)) not in dic: dic[tuple(order(node))]=node else: res.append(dic[tuple(order(node))]) prev.extend([node.left,node.right]) return list(set(res))