Skip to content

Commit

Permalink
Merge pull request #636 from vaskoz/day311
Browse files Browse the repository at this point in the history
Day311
  • Loading branch information
vaskoz committed Jun 29, 2019
2 parents d8edd55 + c457e2d commit 1a4fb35
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,4 @@ problems from
* [Day 307](https://github.com/vaskoz/dailycodingproblem-go/issues/628)
* [Day 309](https://github.com/vaskoz/dailycodingproblem-go/issues/631)
* [Day 310](https://github.com/vaskoz/dailycodingproblem-go/issues/633)
* [Day 311](https://github.com/vaskoz/dailycodingproblem-go/issues/635)
73 changes: 73 additions & 0 deletions day311/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package day311

// PeakIndexNR returns the index of a peak without
// using recursion.
// Runs in O(log N).
func PeakIndexNR(nums []int) int {
if len(nums) == 0 {
return -1
} else if len(nums) == 1 {
return 0
}
low, high := 0, len(nums)-1
for low < high {
mid := (low + high) / 2
switch {
case (mid == 0 || nums[mid-1] <= nums[mid]) &&
(mid == len(nums)-1 || nums[mid+1] <= nums[mid]):
return mid
case mid > 0 && nums[mid-1] > nums[mid]:
high = mid - 1
default:
low = mid + 1
}
}
return low
}

// PeakIndex returns the index of a peak.
// Runs in O(log N).
func PeakIndex(nums []int) int {
if len(nums) == 0 {
return -1
} else if len(nums) == 1 {
return 0
}
return peakIndex(nums, 0, len(nums)-1)
}

func peakIndex(nums []int, low, high int) int {
mid := (low + high) / 2
if (mid == 0 || nums[mid-1] <= nums[mid]) &&
(mid == len(nums)-1 || nums[mid+1] <= nums[mid]) {
return mid
} else if mid > 0 && nums[mid-1] > nums[mid] {
return peakIndex(nums, low, mid-1)
}
return peakIndex(nums, mid+1, high)
}

// PeakIndexBrute returns the index of a peak.
// Runs in O(N).
func PeakIndexBrute(nums []int) int {
if len(nums) == 1 {
return 0
}
for i := range nums {
switch i {
case 0:
if nums[i] > nums[i+1] {
return i
}
case len(nums) - 1:
if nums[i] > nums[i-1] {
return i
}
default:
if nums[i] > nums[i-1] && nums[i] > nums[i+1] {
return i
}
}
}
return -1
}
66 changes: 66 additions & 0 deletions day311/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package day311

import "testing"

// nolint
var testcases = []struct {
nums []int
peakIndex int
}{
{[]int{1, 3, 20, 4, 1, 0}, 2},
{nil, -1},
{[]int{100}, 0},
{[]int{5, 3, 2, 1, 0}, 0},
{[]int{1, 3, 5, 8, 10, 100}, 5},
}

func TestPeakIndexNR(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if peak := PeakIndexNR(tc.nums); peak != tc.peakIndex {
t.Errorf("Expected %v, got %v", tc.peakIndex, peak)
}
}
}

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

func TestPeakIndex(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if peak := PeakIndex(tc.nums); peak != tc.peakIndex {
t.Errorf("Expected %v, got %v", tc.peakIndex, peak)
}
}
}

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

func TestPeakIndexBrute(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
if peak := PeakIndexBrute(tc.nums); peak != tc.peakIndex {
t.Errorf("Expected %v, got %v", tc.peakIndex, peak)
}
}
}

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

0 comments on commit 1a4fb35

Please sign in to comment.