Scala algorithm: Median of two sorted arrays
Published
Algorithm goal
The median value of a sorted list is the value right in the middle. In case the list is even, the average of the two middle elements is taken. For example, the median of [1,2,9] is 2, and the median of [1,2,3,9] is 2.5 (= (2 + 3) / 2).
Efficiently compute the median of two sorted arrays.
Test cases in Scala
assert(median(Array.empty, Array.empty) == None)
assert(median(Array(0), Array.empty) == Some(0))
assert(median(Array.empty, Array(4)) == Some(4))
assert(median(Array(1), Array(1)) == Some(1))
assert(median(Array(0, 1), Array(0)) == Some(0))
assert(median(Array(0), Array(0, 1)) == Some(0))
assert(median(Array(2), Array(1)) == Some(1.5))
assert(median(Array(1), Array(2)) == Some(1.5))
assert(median(Array(1, 2, 3), Array.empty) == Some(2))
assert(median(Array(1, 2, 3), Array(4, 5, 6, 7)) == Some(4))
assert(median(Array(0, 0), Array(0, -1)) == Some(0))
assert(median(Array(0, -1), Array(0, 0)) == Some(0))
assert(median(Array(4, 5, 6, 7), Array(1, 2, 3)) == Some(4))
assert(median(Array(1, 2, 7), Array(4, 5, 6)) == Some(4.5))
assert(median(Array(7), Array(5, 6, 8)) == Some(6.5))
assert(median(Array(7, 20), Array(1)) == Some(7))
assert(median(Array(1, 9), Array(5)) == Some(5))
assert(median(Array(1), Array(0, 0, 0, 1, 1)) == Some(0.5))
assert(median(Array(1), Array(0, 0, 0, 1, 1, 1)) == Some(1))
assert(median(Array(1, 3, 3, 5, 6, 6, 7), Array(7)) == Some(5.5))
Algorithm in Scala
40 lines of Scala (compatible versions 2.13 & 3.0).
Get the full algorithm !
or
'Unlimited Scala Algorithms' gives you access to all the 100 published Scala Algorithms!
Upon purchase, you will be able to Register an account to access all the algorithms on multiple devices.
Explanation
The brute-force solution of adding two arrays to each other requires a sort, which is O(nlogn). The efficient solution is O(n).
In order to approach this problem, first we must consider the length of both arrays, L(A) and L(B): The median of the two lists is at the half-way of L(A)+L(B) combined (≈(L(A)+L(B))/2). So the length of each side must be the same (assuming even case, and one-off otherwise). (this is © from www.scala-algorithms.com)
Assume the largest value of A is smaller than the largest value of B (this is the reason behind doing 'notRightEnd', and 'defRightEnd'). Then we are certain that the last element of the final output is coming from B.
Full explanation is available to subscribers
Scala concepts & Hints
Class Inside Def
Like Def Inside Def, classes can also be defined in defs.
This is particularly useful when defining temporary data types, in particular groupings.
Def Inside Def
A great aspect of Scala is being able to declare functions inside functions, making it possible to reduce repetition.
It is also frequently used in combination with Tail Recursion.
For-comprehension
The for-comprehension is highly important syntatic enhancement in functional programming languages.
Option Type
The 'Option' type is used to describe a computation that either has a result or does not. In Scala, you can 'chain' Option processing, combine with lists and other data structures. For example, you can also turn a pattern-match into a function that return an Option, and vice-versa!
Range
The
(1 to n)
syntax produces a "Range" which is a representation of a sequence of numbers.