Skip to content

Commit

Permalink
Merge 1a1db56 into ea14127
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Dec 1, 2018
2 parents ea14127 + 1a1db56 commit 82cf766
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ problems from
* [Day 90](https://github.com/vaskoz/dailycodingproblem-go/issues/189)
* [Day 91](https://github.com/vaskoz/dailycodingproblem-go/issues/192)
* [Day 92](https://github.com/vaskoz/dailycodingproblem-go/issues/194)
* [Day 93](https://github.com/vaskoz/dailycodingproblem-go/issues/196)
* [Day 94](https://github.com/vaskoz/dailycodingproblem-go/issues/197)
* [Day 95](https://github.com/vaskoz/dailycodingproblem-go/issues/198)
* [Day 96](https://github.com/vaskoz/dailycodingproblem-go/issues/200)
Expand Down
84 changes: 84 additions & 0 deletions day93/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package day93

// BinaryTree is a binary tree: left & right children.
type BinaryTree struct {
Value int
Left, Right *BinaryTree
}

// TreeInfo contains information from a given subtree.
type TreeInfo struct {
IsBST bool
Min int
Max int
Size int
Ans int
AnsPtr *BinaryTree
}

// MaxInt is the largest int.
const MaxInt = int(^uint(0) >> 1)

// MinInt is the smallest int.
const MinInt = -MaxInt - 1

// FindLargestBST will return a pointer to the root of the
// largest BST in the binary tree.
// Runs in O(N) time with no extra space.
func FindLargestBST(tree *BinaryTree) *BinaryTree {
res := sizeOfLargestBST(tree)
return res.AnsPtr
}

// SizeOfLargestBST will return the number of nodes in the
// largest BST in the binary tree.
// Runs in O(N) time with no extra space.
func SizeOfLargestBST(tree *BinaryTree) int {
res := sizeOfLargestBST(tree)
return res.Ans
}

func sizeOfLargestBST(tree *BinaryTree) TreeInfo {
if tree == nil {
return TreeInfo{IsBST: true, Min: MaxInt, Max: MinInt, Size: 0, Ans: 0}
}
if tree.Left == nil && tree.Right == nil {
return TreeInfo{IsBST: true, Min: tree.Value, Max: tree.Value, Size: 1, Ans: 1}
}
left := sizeOfLargestBST(tree.Left)
right := sizeOfLargestBST(tree.Right)
var info TreeInfo
info.Size = 1 + left.Size + right.Size
if left.IsBST && right.IsBST && left.Max < tree.Value && right.Min > tree.Value {
info.Min = min(left.Min, min(right.Min, tree.Value))
info.Max = max(right.Max, max(left.Max, tree.Value))
info.Ans = info.Size
info.AnsPtr = tree
info.IsBST = true
return info
}
if left.Ans > right.Ans {
info.Ans = left.Ans
info.AnsPtr = left.AnsPtr
} else {
info.Ans = right.Ans
info.AnsPtr = right.AnsPtr
}
info.Ans = max(left.Ans, right.Ans)
info.IsBST = false
return info
}

func min(a, b int) int {
if a < b {
return a
}
return b
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
102 changes: 102 additions & 0 deletions day93/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package day93

import "testing"

var testcases = []struct {
tree *BinaryTree
largestBSTSize int
largestBST *BinaryTree
}{
{&BinaryTree{
Value: 60,
Left: &BinaryTree{
Value: 65,
Left: &BinaryTree{
Value: 50,
Left: nil,
Right: nil,
},
Right: nil,
},
Right: &BinaryTree{
Value: 70,
Left: nil,
Right: nil,
},
}, 2, nil},
{&BinaryTree{
Value: 60,
Left: &BinaryTree{
Value: 90,
Left: nil,
Right: nil,
},
Right: &BinaryTree{
Value: 65,
Left: nil,
Right: &BinaryTree{
Value: 70,
Left: nil,
Right: nil,
},
},
}, 2, nil},
{&BinaryTree{
Value: 60,
Left: &BinaryTree{
Value: 40,
Left: nil,
Right: nil,
},
Right: &BinaryTree{
Value: 65,
Left: nil,
Right: &BinaryTree{
Value: 70,
Left: nil,
Right: nil,
},
},
}, 4, nil},
}

func answerKey() {
testcases[0].largestBST = testcases[0].tree.Left
testcases[1].largestBST = testcases[1].tree.Right
testcases[2].largestBST = testcases[2].tree
}

func TestSizeOfLargestBST(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if result := SizeOfLargestBST(tc.tree); result != tc.largestBSTSize {
t.Errorf("Expected %v got %v", tc.largestBSTSize, result)
}
}
}

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

func TestFindLargestBST(t *testing.T) {
answerKey()
t.Parallel()
for _, tc := range testcases {
if result := FindLargestBST(tc.tree); result != tc.largestBST {
t.Errorf("Expected %v got %v", tc.largestBST, result)
}
}
}

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

0 comments on commit 82cf766

Please sign in to comment.