-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add: median of medians algorithm solution for Miscellaneous
- Loading branch information
1 parent
7db4f1b
commit f4af3e1
Showing
2 changed files
with
98 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package Miscellaneous | ||
|
||
import ( | ||
"sort" | ||
) | ||
|
||
// | ||
// coverage time complexity: O(n), worst O(n) | ||
// space complexity: O(n) | ||
// | ||
func findKthSmallestNumberUsingMedianOfMedians(nums []int, k int) int { | ||
if k > len(nums) { | ||
return -1 | ||
} | ||
return findPivotRecursive(nums, k, 0, len(nums)-1) | ||
} | ||
|
||
func findPivotRecursive(nums []int, k, start, end int) int { | ||
p := partitionMom(nums, start, end) | ||
if p == k-1 { | ||
return nums[p] | ||
} | ||
if p > k-1 { | ||
return findPivotRecursive(nums, k, start, p-1) | ||
} | ||
return findPivotRecursive(nums, k, p+1, end) | ||
} | ||
|
||
func partitionMom(nums []int, low, high int) int { | ||
if low == high { | ||
return low | ||
} | ||
|
||
median := medianOfMedians(nums, low, high) | ||
// median as pivot | ||
// swap high and median | ||
for i := low; i < high; i++ { | ||
if nums[i] == median { | ||
nums[i], nums[high] = nums[high], nums[i] | ||
break | ||
} | ||
} | ||
|
||
pivot := nums[high] | ||
i := low - 1 | ||
for j := low; j < high; j++ { | ||
if nums[j] < pivot { | ||
i++ | ||
nums[i], nums[j] = nums[j], nums[i] | ||
} | ||
} | ||
nums[i+1], nums[high] = nums[high], nums[i+1] | ||
return i + 1 | ||
} | ||
|
||
func medianOfMedians(nums []int, low, high int) int { | ||
n := high - low + 1 | ||
if n < 5 { | ||
return nums[low] | ||
} | ||
|
||
numOfPartitions := n / 5 | ||
medians := make([]int, numOfPartitions) | ||
for i := 0; i < numOfPartitions; i++ { | ||
partStart := low + i*5 | ||
sort.Ints(nums[partStart : partStart+5]) | ||
medians[i] = nums[partStart+2] | ||
} | ||
|
||
return partitionMom(medians, 0, numOfPartitions-1) | ||
} |
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,27 @@ | ||
package Miscellaneous | ||
|
||
import "testing" | ||
|
||
func Test_findKthSmallestNumberUsingMedianOfMedians(t *testing.T) { | ||
type args struct { | ||
nums []int | ||
k int | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want int | ||
}{ | ||
{"case1", args{[]int{1, 5, 12, 2, 11, 5}, 3}, 5}, | ||
{"case2", args{[]int{1, 5, 12, 2, 11, 5}, 4}, 5}, | ||
{"case3", args{[]int{5, 12, 11, -1, 12}, 3}, 11}, | ||
{"case4", args{[]int{5, 12, 11, -1, 12}, 6}, -1}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := findKthSmallestNumberUsingMedianOfMedians(tt.args.nums, tt.args.k); got != tt.want { | ||
t.Errorf("findKthSmallestNumberUsingMedianOfMedians() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |