Skip to content

Commit

Permalink
Solve the "Compute the lowest common ancestor in a binary tree"
Browse files Browse the repository at this point in the history
  • Loading branch information
mrekucci committed Oct 22, 2015
1 parent 15235f0 commit 92ab2cf
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Binary Trees
|--------------------------------------------------------------------------|:------------:|:-----------:|
| [Test if a binary tree is balanced][144] | [tests][145] ||
| [Test if a binary tree is symmetric][146] | [tests][147] ||
| [Compute the lowest common ancestor in a binary tree][148] | [tests][149] | |
| [Compute the lowest common ancestor in a binary tree][148] | [tests][149] | |
| [Compute the LCA when nodes have parent pointers][150] | [tests][151] | |
| [Sum the root-to-leaf paths in a binary tree][152] | [tests][153] | |
| [Find a root to leaf path with specified sum][154] | [tests][155] | |
Expand Down Expand Up @@ -544,8 +544,8 @@ Honors Class
[145]: btrees/balanced_test.go
[146]: btrees/symmetric.go
[147]: btrees/symmetric_test.go
[148]: in_progress.md
[149]: in_progress.md
[148]: btrees/lca.go
[149]: btrees/lca_test.go
[150]: in_progress.md
[151]: in_progress.md
[152]: in_progress.md
Expand Down
43 changes: 43 additions & 0 deletions btrees/lca.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2015, Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.txt file.

package btrees

// findLCA walks the binary tree t and returns lowest common
// ancestor for the nodes n0 and n1. The cnt is 0, 1, or 2
// depending on nodes (n0, n1) presented in the tree.
func findLCA(t, n0, n1 *BTree) (cnt int, ancestor *BTree) {
if t == nil {
return 0, nil // Base case.
}

// Postorder walk.
lc, la := findLCA(t.right, n0, n1)
if lc == 2 {
return lc, la
}
rc, ra := findLCA(t.left, n0, n1)
if rc == 2 {
return rc, ra
}

cnt = lc + rc
if t == n0 {
cnt++
}
if t == n1 {
cnt++
}
if cnt == 2 {
ancestor = t
}
return cnt, ancestor
}

// LCA returns the lowest common ancestor in
// the binary tree t for the nodes n0, n1.
func LCA(t, n0, n1 *BTree) *BTree {
_, a := findLCA(t, n0, n1)
return a
}
45 changes: 45 additions & 0 deletions btrees/lca_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2015, Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.txt file.

package btrees

import "testing"

func TestLCA(t *testing.T) {
// A Binary Tree of height 5.
tree := &BTree{"A",
&BTree{"B",
&BTree{"C",
&BTree{"D", nil, nil},
&BTree{"E", nil, nil}},
&BTree{"F",
nil,
&BTree{"G",
&BTree{"H", nil, nil},
nil}}},
&BTree{"I",
&BTree{"J",
nil,
&BTree{"K",
&BTree{"L",
nil,
&BTree{"M", nil, nil}},
&BTree{"N", nil, nil}}},
&BTree{"O",
nil,
&BTree{"P", nil, nil}}}}

for _, test := range []struct {
t, n0, n1 *BTree
want *BTree
}{
{&BTree{"TREE", nil, nil}, nil, nil, nil},
{tree, tree.left, tree.right, tree}, // n0 = B; n1 = I; want = A
{tree, tree.right.left.right.left.right, tree.right.left.right.right, tree.right.left.right}, // n0 = M; n1 = N; want = K
} {
if got := LCA(test.t, test.n0, test.n1); got != test.want {
t.Errorf("LCA(%v, %v, %v) = %v; want %v", test.t, test.n0, test.n1, got, test.want)
}
}
}

0 comments on commit 92ab2cf

Please sign in to comment.