-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
110 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package day43 | ||
|
||
import "fmt" | ||
|
||
var errStackEmpty = fmt.Errorf("Stack is empty") | ||
|
||
// maxIntStack is implemented using O(N) extra memory. | ||
type maxIntStack struct { | ||
stack []int | ||
} | ||
|
||
// MaxIntStack represents that API of a stack of ints that push, pop and find the max value. | ||
type MaxIntStack interface { | ||
Push(val int) | ||
Pop() (int, error) | ||
Max() (int, error) | ||
} | ||
|
||
// NewMaxIntStack returns a new instance. | ||
func NewMaxIntStack() MaxIntStack { | ||
return &maxIntStack{} | ||
} | ||
|
||
func (mis *maxIntStack) Push(val int) { | ||
var max int | ||
if len(mis.stack) == 0 { | ||
max = val | ||
} else { | ||
max = mis.stack[len(mis.stack)-2] | ||
if val > max { | ||
max = val | ||
} | ||
} | ||
mis.stack = append(mis.stack, max, val) | ||
} | ||
|
||
func (mis *maxIntStack) Pop() (int, error) { | ||
if len(mis.stack) == 0 { | ||
return 0, StackEmptyError() | ||
} | ||
var result int | ||
result, mis.stack = mis.stack[len(mis.stack)-1], mis.stack[:len(mis.stack)-2] | ||
return result, nil | ||
} | ||
|
||
func (mis *maxIntStack) Max() (int, error) { | ||
if len(mis.stack) == 0 { | ||
return 0, StackEmptyError() | ||
} | ||
return mis.stack[len(mis.stack)-2], nil | ||
} | ||
|
||
// StackEmptyError returns the instance of the error representing an empty stack. | ||
func StackEmptyError() error { | ||
return errStackEmpty | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package day43 | ||
|
||
import "testing" | ||
|
||
var testcases = []struct { | ||
input []int | ||
max []int | ||
}{ | ||
{[]int{1, 2, 3, 4, 5, 6}, []int{1, 2, 3, 4, 5, 6}}, | ||
} | ||
|
||
func TestMaxIntStack(t *testing.T) { | ||
t.Parallel() | ||
for tcid, tc := range testcases { | ||
stack := NewMaxIntStack() | ||
for i, push := range tc.input { | ||
stack.Push(push) | ||
if max, err := stack.Max(); err != nil || max != tc.max[i] { | ||
t.Errorf("TC%d push expected,got max (%d,%d) error should be nil (%v)", | ||
tcid, tc.max[i], max, err) | ||
} | ||
} | ||
for i := range tc.input { | ||
if max, err := stack.Max(); err != nil || max != tc.max[len(tc.max)-1-i] { | ||
t.Errorf("TC%d pre-pop expected,got max (%d,%d) error should be nil (%v)", | ||
tcid, tc.max[len(tc.max)-1-i], max, err) | ||
} | ||
if val, err := stack.Pop(); err != nil || val != tc.input[len(tc.input)-1-i] { | ||
t.Errorf("TC%d pop expected,got val (%d,%d) error should be nil (%v)", | ||
tcid, tc.input[len(tc.input)-1-i], val, err) | ||
} | ||
} | ||
if _, err := stack.Pop(); err != StackEmptyError() { | ||
t.Errorf("Stack should be empty and return an error on Pop()") | ||
} | ||
if _, err := stack.Max(); err != StackEmptyError() { | ||
t.Errorf("Stack should be empty and return an error on Max()") | ||
} | ||
} | ||
} | ||
|
||
func BenchmarkMaxIntStack(b *testing.B) { | ||
for i := 0; i < b.N; i++ { | ||
for _, tc := range testcases { | ||
stack := NewMaxIntStack() | ||
for _, push := range tc.input { | ||
stack.Push(push) | ||
stack.Max() | ||
stack.Pop() | ||
} | ||
} | ||
} | ||
} |