-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path1361-ValidateBinaryTreeNodes.go
More file actions
157 lines (144 loc) · 5.25 KB
/
1361-ValidateBinaryTreeNodes.go
File metadata and controls
157 lines (144 loc) · 5.25 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package main
// 1361. Validate Binary Tree Nodes
// You have n binary tree nodes numbered from 0 to n - 1 where node i has two children leftChild[i] and rightChild[i],
// return true if and only if all the given nodes form exactly one valid binary tree.
// If node i has no left child then leftChild[i] will equal -1, similarly for the right child.
// Note that the nodes have no values and that we only use the node numbers in this problem.
// Example 1:
// <img src="https://assets.leetcode.com/uploads/2019/08/23/1503_ex1.png" />
// Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]
// Output: true
// Example 2:
// <img src="https://assets.leetcode.com/uploads/2019/08/23/1503_ex2.png" />
// Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]
// Output: false
// Example 3:
// <img src="https://assets.leetcode.com/uploads/2019/08/23/1503_ex3.png" />
// Input: n = 2, leftChild = [1,0], rightChild = [-1,-1]
// Output: false
// Constraints:
// n == leftChild.length == rightChild.length
// 1 <= n <= 10^4
// -1 <= leftChild[i], rightChild[i] <= n - 1
import "fmt"
// // 解答错误 45 / 51
// func validateBinaryTreeNodes(n int, leftChild []int, rightChild []int) bool {
// checker := make([]int, n)
// // check parent count: [0, 1]
// for i := 0; i < n; i++ {
// if leftChild[i] != -1 {
// checker[leftChild[i]]++
// if checker[leftChild[i]] > 1 {
// return false
// }
// }
// if rightChild[i] != -1 {
// checker[rightChild[i]]++
// if checker[rightChild[i]] > 1 {
// return false
// }
// }
// }
// // check root count == 1
// rootCount := 0
// for _, v := range checker {
// if v == 0 {
// rootCount++
// if rootCount > 1 {
// return false
// }
// }
// }
// return rootCount == 1
// }
func validateBinaryTreeNodes(n int, leftChild []int, rightChild []int) bool {
treeMap := make(map[int]int)
for i := 0; i < n; i++ {
treeMap[leftChild[i]]++
treeMap[rightChild[i]]++
}
// find root node
root := -1
for i := 0; i < n; i++ {
if treeMap[i] == 0 {
if root != -1 { return false } // 存在两个根节点返回 false
root = i
continue
}
if treeMap[i] != 1 { return false } // 存在两个父节点返回 false
}
if root == -1 { return false } // 不存在根节点,说明是有循环
// BFS检查树
queue := []int{ root }
treeMap[root]++
for len(queue) != 0 {
tmp := []int{}
for _, n := range queue {
// 被遍历到的点从原来的1变为0
treeMap[n]--
if leftChild[n] != -1 {
tmp = append(tmp, leftChild[n])
}
if rightChild[n] != -1 {
tmp = append(tmp, rightChild[n])
}
}
queue = tmp
}
for n := range treeMap { // 检查是否还存在没遍历到的节点
if n == -1 { continue }
if treeMap[n] != 0 { return false }
}
return true
}
func validateBinaryTreeNodes1(n int, left []int, right []int) bool {
in := make([]int, n)
for i := 0; i < n; i++ {
if left[i] != -1 {
in[left[i]]++
}
if right[i] != -1 {
in[right[i]]++
}
}
count0, countOther,rootIndex := 0, 0, 0
for i := 0; i < n; i++ {
if in[i] == 0 {
rootIndex = i
count0++
}
if in[i] > 1 {
countOther++
}
}
visited := make([]bool, n)
// 特别:一个独立的环 加上 一颗正常的树,就得正常判断一下
var notCircle func(rootIdx int, left, right []int, visit []bool) int
notCircle = func(rootIdx int, left, right []int, visit []bool) int {
if rootIdx == -1 || visit[rootIdx] { return 0 }
visit[rootIdx] = true
l, r := notCircle(left[rootIdx], left, right, visit), notCircle(right[rootIdx], left, right, visit)
return 1 + l + r
}
return count0 == 1 && countOther == 0 && notCircle(rootIndex, left, right, visited) == n
}
func main() {
// Example 1:
// <img src="https://assets.leetcode.com/uploads/2019/08/23/1503_ex1.png" />
// Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]
// Output: true
fmt.Println(validateBinaryTreeNodes(4, []int{1,-1,3,-1},[]int{2,-1,-1,-1})) // true
// Example 2:
// <img src="https://assets.leetcode.com/uploads/2019/08/23/1503_ex2.png" />
// Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]
// Output: false
fmt.Println(validateBinaryTreeNodes(4, []int{1,-1,3,-1},[]int{2,3,-1,-1})) // false
// Example 3:
// <img src="https://assets.leetcode.com/uploads/2019/08/23/1503_ex3.png" />
// Input: n = 2, leftChild = [1,0], rightChild = [-1,-1]
// Output: false
fmt.Println(validateBinaryTreeNodes(2, []int{1,0},[]int{-1,-1})) // false
fmt.Println(validateBinaryTreeNodes1(4, []int{1,-1,3,-1},[]int{2,-1,-1,-1})) // true
fmt.Println(validateBinaryTreeNodes1(4, []int{1,-1,3,-1},[]int{2,3,-1,-1})) // false
fmt.Println(validateBinaryTreeNodes1(2, []int{1,0},[]int{-1,-1})) // false
}