Last active
June 22, 2020 09:48
-
-
Save cfc1020/60de435c89401bad1d796907e4eac3a6 to your computer and use it in GitHub Desktop.
Finding the k-th largest element from the array effectively and simply as well
This file contains hidden or 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
require 'benchmark' | |
examples = [] | |
res1 = [] | |
res2 = [] | |
def f1(arr, k) | |
arr.sort[arr.size - k] | |
end | |
def f2(arr, k) | |
left = 0 | |
right = arr.size - 1 | |
f = arr.size - k | |
pivot = -1 | |
while left <= right do | |
pivot = partition(arr, left, right) | |
if pivot == f | |
return arr[pivot] | |
elsif pivot < f | |
left = pivot + 1 | |
else | |
right = pivot - 1 | |
end | |
end | |
end | |
def partition(arr, left, right) | |
pivot = left | |
while left < right do | |
if arr[left] < arr[right] | |
arr[pivot], arr[left] = arr[left], arr[pivot] | |
pivot += 1 | |
end | |
left += 1 | |
end | |
arr[pivot], arr[right] = arr[right], arr[pivot] | |
return pivot | |
end | |
Benchmark.bm do |x| | |
8.times do |i| | |
x.report("populate##{i}") { examples << Array.new(10**i) { rand(1..1_000_000) } } | |
end | |
examples.each_with_index do |a, i| | |
x.report("sort##{i}") { res1 << f1(a, 3) } | |
end | |
examples.each_with_index do |a, i| | |
x.report("partition##{i}") { res2 << f2(a, 3) } | |
end | |
end | |
p res1 | |
p res2 | |
puts res1 == res2 |
This file contains hidden or 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
package main | |
import "fmt" | |
// An algorithm to find the k-th largest element from the array | |
// Time complexity is O(2n) | |
// Space complexity is a few pointers and swaps the elements | |
func main() { | |
fmt.Println(findKthLargestElement([]int{15, 16, 11, 18, 12, 3, 4, 5, 0, 6}, 3)) // The answer should be 15 | |
} | |
// Assumptions: | |
// - K is in range [1, length] | |
// - The array has at least one element | |
func findKthLargestElement(arr []int, k int) int { | |
left := 0 | |
right := len(arr) - 1 | |
for left <= right { | |
pivatIndex := partition(arr, left, right) | |
if pivatIndex == len(arr) - k { | |
return arr[pivatIndex] | |
} else if pivatIndex < len(arr) - k { | |
left = pivatIndex + 1 | |
} else { | |
right = pivatIndex - 1 | |
} | |
} | |
return -1 // means error | |
} | |
func partition(arr []int, left, right int) int { | |
fmt.Println("In: ", arr, left, right) | |
index := left | |
pivot := arr[right] | |
for left < right { | |
if arr[left] <= pivot { | |
arr[left], arr[index] = arr[index], arr[left] | |
index += 1 | |
} | |
left += 1 | |
} | |
arr[right], arr[index] = arr[index], arr[right] | |
fmt.Println("Out: ", arr, index) | |
return index | |
} |
Author
cfc1020
commented
Jun 22, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment