Skip to content

Commit

Permalink
Merge pull request #372 from vaskoz/day179
Browse files Browse the repository at this point in the history
Day179
  • Loading branch information
vaskoz committed Feb 18, 2019
2 parents ff0c611 + c256a30 commit 2799dd2
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,4 @@ problems from
* [Day 176](https://github.com/vaskoz/dailycodingproblem-go/issues/364)
* [Day 177](https://github.com/vaskoz/dailycodingproblem-go/issues/365)
* [Day 178](https://github.com/vaskoz/dailycodingproblem-go/issues/367)
* [Day 179](https://github.com/vaskoz/dailycodingproblem-go/issues/371)
51 changes: 51 additions & 0 deletions day179/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package day179

const maxInt = int(^uint(0) >> 1)
const minInt = -maxInt - 1

// BinaryTree is a binary tree of integers.
type BinaryTree struct {
Value int
Left, Right *BinaryTree
}

// BuildTreeFromPostorder reconstructs a binary tree from
// a postorder traversal.
// Runs in O(N^2) time.
func BuildTreeFromPostorder(lst []int) *BinaryTree {
if len(lst) == 0 {
return nil
}
root := &BinaryTree{lst[len(lst)-1], nil, nil}
lst = lst[:len(lst)-1]
i := len(lst) - 1
for ; i >= 0 && lst[i] > root.Value; i-- {
}
root.Left = BuildTreeFromPostorder(lst[:i+1])
root.Right = BuildTreeFromPostorder(lst[i+1:])
return root
}

// BuildTreeFromPostorderLinear reconstructs a binary tree from
// a postorder traversal.
// Runs in O(N) time.
func BuildTreeFromPostorderLinear(lst []int) *BinaryTree {
return buildTreeFromPostorderLinear(&lst, minInt, maxInt)
}

func buildTreeFromPostorderLinear(lst *[]int, min, max int) *BinaryTree {
if len(*lst) == 0 {
return nil
}
var root *BinaryTree
key := (*lst)[len(*lst)-1]
if key > min && key < max {
root = &BinaryTree{key, nil, nil}
*lst = (*lst)[:len(*lst)-1]
if len(*lst) > 0 {
root.Right = buildTreeFromPostorderLinear(lst, key, max)
root.Left = buildTreeFromPostorderLinear(lst, min, key)
}
}
return root
}
83 changes: 83 additions & 0 deletions day179/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package day179

import "testing"

var testcases = []struct {
postorder []int
expected *BinaryTree
}{
{[]int{2, 4, 3, 8, 7, 5}, &BinaryTree{
5,
&BinaryTree{
3,
&BinaryTree{2, nil, nil},
&BinaryTree{4, nil, nil},
},
&BinaryTree{
7,
nil,
&BinaryTree{8, nil, nil},
},
}},
{[]int{1, 7, 5, 50, 40, 10}, &BinaryTree{
10,
&BinaryTree{
5,
&BinaryTree{1, nil, nil},
&BinaryTree{7, nil, nil},
},
&BinaryTree{
40,
nil,
&BinaryTree{50, nil, nil},
},
}},
{[]int{}, nil},
}

func TestBuildTreeFromPostorder(t *testing.T) {
t.Parallel()
for tcid, tc := range testcases {
if result := BuildTreeFromPostorder(tc.postorder); !equal(result, tc.expected) {
t.Errorf("Trees don't match for tcid%d", tcid)
}
}
}

func BenchmarkBuildTreeFromPostorder(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
BuildTreeFromPostorder(tc.postorder)
}
}
}

func TestBuildTreeFromPostorderLinear(t *testing.T) {
t.Parallel()
for tcid, tc := range testcases {
if result := BuildTreeFromPostorderLinear(tc.postorder); !equal(result, tc.expected) {
t.Errorf("Trees don't match for tcid%d", tcid)
}
}
}

func BenchmarkBuildTreeFromPostorderLinear(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
BuildTreeFromPostorderLinear(tc.postorder)
}
}
}

func equal(a, b *BinaryTree) bool {
if a == nil && b != nil {
return false
} else if a != nil && b == nil {
return false
} else if a == nil && b == nil {
return true
} else if a.Value != b.Value {
return false
}
return equal(a.Left, b.Left) && equal(a.Right, b.Right)
}

0 comments on commit 2799dd2

Please sign in to comment.