Skip to content

Commit 3c19bdf

Browse files
committed
Add first-common-ancestor-lcci
1 parent b35af75 commit 3c19bdf

File tree

7 files changed

+140
-0
lines changed

7 files changed

+140
-0
lines changed

algorithms/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
|0331|[验证二叉树的前序序列化](https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree/)|[go](./tree/331.isValidSerialization.go)|M|
5454
|0344|[反转字符串](https://leetcode-cn.com/problems/reverse-string/)|[go](./mystring/344.reverseString.go)|S|
5555
|0347|[前 K 个高频元素](https://leetcode-cn.com/problems/top-k-frequent-elements/)|[go](./myheap/347.topkFrequent.go)|M|
56+
|0404|[检查平衡性](https://leetcode-cn.com/problems/check-balance-lcci/)|[go](./tree/404.isBalanced.go)|S|
57+
|0408|[首个共同祖先](https://leetcode-cn.com/problems/first-common-ancestor-lcci/)|[go](./tree/408.lowestCommonAncestor.go)|M|
5658
|0412|[Fizz Buzz](https://leetcode-cn.com/problems/fizz-buzz/)|[go](./mystring/412.fizzBuzz.go)|S|
5759
|0442|[数组中重复的数据](https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/)|[go](./myarray/442.findDuplicates.go)|M|
5860
|0468|[验证IP地址](https://leetcode-cn.com/problems/validate-ip-address/submissions/)|[go](./mystring/468.validIPAddress.go)|M|

algorithms/kit/Tcase.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
package kit
22

3+
import (
4+
"encoding/json"
5+
)
6+
37
// CaseEntry delcare
48
type CaseEntry struct {
59
Name string
610
Input interface{}
711
Expected interface{}
812
}
13+
14+
func (c CaseEntry) String() string {
15+
bc, _ := json.Marshal(c)
16+
return string(bc)
17+
}

algorithms/kit/TreeNode.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,17 @@ func Tree2Postorder(root *TreeNode) []int { // {{{
104104
res = append(res, root.Val)
105105
return res
106106
} // }}}
107+
108+
// FindTargetNode 返回 Val = target 的 TreeNode
109+
// 假设root中一定有 node.Val = target
110+
func FindTargetNode(root *TreeNode, target int) *TreeNode {
111+
if root == nil || root.Val == target {
112+
return root
113+
}
114+
115+
if res := FindTargetNode(root.Left, target); res != nil {
116+
return res
117+
}
118+
119+
return FindTargetNode(root.Right, target)
120+
}

algorithms/tree/404.isBalanced.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package tree
2+
3+
import (
4+
"math"
5+
)
6+
7+
func isBalanced(root *TreeNode) bool {
8+
if root == nil {
9+
return true
10+
}
11+
12+
if math.Abs(depth(root.Left)-depth(root.Right)) <= 1 {
13+
return isBalanced(root.Left) && isBalanced(root.Right)
14+
}
15+
16+
return false
17+
}
18+
19+
func depth(root *TreeNode) float64 {
20+
if root == nil {
21+
return 0
22+
}
23+
24+
return math.Max(depth(root.Left), depth(root.Right)) + 1
25+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package tree
2+
3+
import (
4+
"testing"
5+
6+
"Leetcode/algorithms/kit"
7+
)
8+
9+
// run: go test -v -run Test_isBalanced
10+
func Test_isBalanced(t *testing.T) {
11+
cases := []kit.CaseEntry{
12+
{
13+
Name: "x1",
14+
Input: []int{3, 9, 20, null, null, 15, 7, 1},
15+
Expected: true,
16+
},
17+
{
18+
Name: "x2",
19+
Input: []int{1, 2, 2, 3, 3, null, null, 4, 4},
20+
Expected: false,
21+
},
22+
{
23+
Name: "x3",
24+
Input: []int{},
25+
Expected: true,
26+
},
27+
// add more test cases
28+
}
29+
30+
for _, tt := range cases {
31+
t.Run(tt.Name, func(t *testing.T) {
32+
root := kit.Ints2Tree(tt.Input.([]int))
33+
if output := isBalanced(root); output != tt.Expected.(bool) {
34+
t.Errorf("isBalanced(%v)=%t, expected=%v", tt.Input, output, tt.Expected)
35+
}
36+
})
37+
}
38+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package tree
2+
3+
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
4+
if root == nil || root == p || root == q {
5+
return root
6+
}
7+
8+
left := lowestCommonAncestor(root.Left, p, q)
9+
right := lowestCommonAncestor(root.Right, p, q)
10+
if left != nil && right != nil {
11+
return root
12+
} else if left == nil {
13+
return right
14+
} else {
15+
return left
16+
}
17+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package tree
2+
3+
import (
4+
"testing"
5+
6+
"Leetcode/algorithms/kit"
7+
)
8+
9+
// run: go test -v -run Test_lowestCommonAncestor
10+
func Test_lowestCommonAncestor(t *testing.T) {
11+
cases := []kit.CaseEntry{
12+
{
13+
Name: "x1",
14+
Input: map[string]interface{}{
15+
"root": []int{3, 5, 1, 6, 2, 0, 8, null, null, 7, 4},
16+
"p": 5,
17+
"q": 1,
18+
},
19+
Expected: 3,
20+
},
21+
}
22+
23+
for _, tt := range cases {
24+
t.Run(tt.Name, func(t *testing.T) {
25+
input := tt.Input.(map[string]interface{})
26+
root := kit.Ints2Tree(input["root"].([]int))
27+
p := kit.FindTargetNode(root, input["p"].(int))
28+
q := kit.FindTargetNode(root, input["q"].(int))
29+
expected := kit.FindTargetNode(root, tt.Expected.(int))
30+
if output := lowestCommonAncestor(root, p, q); output != expected {
31+
t.Errorf("lowestCommonAncestor(%v, %d, %d)=%d, expected=%d", input["root"], p.Val, q.Val, output.Val, expected.Val)
32+
}
33+
})
34+
}
35+
}

0 commit comments

Comments
 (0)