2021-02-07:给定两棵二叉树的头节点head1和head2,如何判断head1中是否有某个子树的结构和head2完全一样?

福哥答案2021-02-07:

对head1和head2序列化为str1和str2。然后用kmp算法去判断str2是否是str1的子串。如果是,head2是子树;如果不是,head2不是子树。

代码用golang编写,代码如下:

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main
 
import "fmt"
 
func main() {
    root := &TreeNode{}
    root.Val = 1
 
    root.Left = &TreeNode{}
    root.Left.Val = 2
 
    root.Right = &TreeNode{}
    root.Right.Val = 3
 
    root.Left.Right = &TreeNode{}
    root.Left.Right.Val = 4
 
    root.Right.Left = &TreeNode{}
    root.Right.Left.Val = 5
 
    fmt.Println(IsSubTree(root, root.Right))
 
}
 
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}
 
//序列化
func serialize(head *TreeNode) string {
    ansVal := ""
    ans := &ansVal
    process(head, ans)
    return (*ans)[1:]
}
 
func process(head *TreeNode, ans *string) {
    if head == nil {
        *ans += ",N"
        return
    }
    *ans += fmt.Sprintf(",%d", head.Val)
    process(head.Left, ans)
    //*ans += fmt.Sprintf(",%d", head.Val)
    process(head.Right, ans)
    //*ans += fmt.Sprintf(",%d", head.Val)
}
func getNextArr(m string) []int {
    mLen := len(m)
    if mLen == 1 {
        return []int{-1}
    }
    ret := make([]int, mLen)
    ret[0] = -1
    cn := 0
    for i := 2; i < mLen; i++ {
        if m[i] == m[cn] {
            cn++
            ret[i] = cn
            i++
        } else if cn > 0 {
            cn = ret[cn]
        } else {
            ret[i] = 0
            i++
        }
    }
    return ret
}
 
//求子串位置
func kmp(s string, m string) int {
    sLen := len(s)
    mLen := len(m)
    if sLen < mLen {
        return -1
    }
    next := getNextArr(m)
    x := 0
    y := 0
    for x < sLen && y < mLen {
        if s[x] == m[y] {
            x++
            y++
        } else if next[y] >= 0 {
            y = next[y]
        } else {
            x++
        }
    }
    if y == mLen {
        return x - y
    } else {
        return -1
    }
}
 
//求是否是子树
func IsSubTree(head1 *TreeNode, head2 *TreeNode) bool {
    if head2 == nil {
        return true
    }
    if head1 == nil {
        return false
    }
    if kmp(serialize(head1), serialize(head2)) >= 0 {
        return true
    } else {
        return false
    }
}

  

执行结果如下:

 

 


***
[评论](https://user.qzone.qq.com/3182319461/blog/1612654678)

posted @   福大大架构师每日一题  阅读(102)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示