572. 另一棵树的子树
给你两棵二叉树 root
和 subRoot
。检验 root
中是否包含和 subRoot
具有相同结构和节点值的子树。如果存在,返回 true
;否则,返回 false
。
二叉树 tree
的一棵子树包括 tree
的某个节点和这个节点的所有后代节点。tree
也可以看做它自身的一棵子树。
示例 1:
输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true
示例 2:
输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false
提示:
root
树上的节点数量范围是 [1, 2000]
subRoot
树上的节点数量范围是 [1, 1000]
-104 <= root.val <= 104
-104 <= subRoot.val <= 104
第一种方法:先深度优先 || 先序遍历主树,直到找到和 subRoot 相同值的节点,再以此为起点与 subRoot 做比较。属于暴力深搜的一种。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 func isSubtree (s *TreeNode, t *TreeNode) bool { if s == nil { return false } return check(s, t) || isSubtree(s.Left, t) || isSubtree(s.Right, t) } func check (a, b *TreeNode) bool { if a == nil && b == nil { return true } if a == nil || b == nil { return false } if a.Val == b.Val { return check(a.Left, b.Left) && check(a.Right, b.Right) } return false }
第二种方法:利用树的性质,将空子树补全,这样能得到唯一的一个先序遍历结果,然后判断 subRoot 的遍历结果是否是 root 遍历结果的子串,即可确认是否是题目要求的子树。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 func isSubtree (s *TreeNode, t *TreeNode) bool { maxEle := math.MinInt32 getMaxElement(s, &maxEle) getMaxElement(t, &maxEle) lNull := maxEle + 1 rNull := maxEle + 2 sl, tl := getDfsOrder(s, []int {}, lNull, rNull), getDfsOrder(t, []int {}, lNull, rNull) return kmp(sl, tl) } func kmp (s, t []int ) bool { sLen, tLen := len (s), len (t) fail := make ([]int , sLen) for i := 0 ; i < sLen; i++ { fail[i] = -1 } for i, j := 1 , -1 ; i < tLen; i++ { for j != -1 && t[i] != t[j+1 ] { j = fail[j] } if t[i] == t[j+1 ] { j++ } fail[i] = j } for i, j := 0 , -1 ; i < sLen; i++ { for j != -1 && s[i] != t[j+1 ] { j = fail[j] } if s[i] == t[j+1 ] { j++ } if j == tLen - 1 { return true } } return false } func getDfsOrder (t *TreeNode, list []int , lNull, rNull int ) []int { if t == nil { return list } list = append (list, t.Val) if t.Left != nil { list = getDfsOrder(t.Left, list, lNull, rNull) } else { list = append (list, lNull) } if t.Right != nil { list = getDfsOrder(t.Right, list, lNull, rNull) } else { list = append (list, rNull) } return list } func getMaxElement (t *TreeNode, maxEle *int ) { if t == nil { return } if t.Val > *maxEle { *maxEle = t.Val } getMaxElement(t.Left, maxEle) getMaxElement(t.Right, maxEle) }