Hi, I'm Gayle Laakmann McDowell, author of Cracking the Coding Interview. Today I want
to cover binary search. So binary search
is a very intuitive algorithm, and I'm going
to show how intuitive it is by giving an
example. You're a teacher and you're
teaching a group of students, a very
large class of 300 students. And you have
their papers alphabetized out in front of
you, when a student Zach Peters comes up
to get his paper back. You
probably wouldn't go through the papers
starting with Alex to Andy to Andrew and
then to Bob and Brenda and Brandy and into
Chris and Cristine, and you probably
wouldn't do that way. What you would probably
do is open the stack of
papers to roughly halfway through the
papers and compare it. Zach Peters? Well
you open up halfway through and you
see Michael Matters there and you say
okay Zach Peters after that name. And
then you take the second stack of papers
and treat it as its own little stack and
you'd again say, ok let me open up to its
midpoint. Maybe we see Sarah. Well is
Sarah before or after Zach Peters? And
then you just go and repeat this process
over and over and over again until you
find Zach's paper or until you find out
Zach can't be in here. And this is the
basics of binary search. So in an integer
array that looks like this, you take some
element that you're looking for, like 13,
and you compare it to the midpoint, and
it has to be a sorted array for this to
work,
it's very important, and you compare it to the
midpoint. 13 is less than this midpoint
and so 13, if it's in the array at all, it has
to be on the left side. And then you repeat
this process on the left side and say
let me look at the midpoint of the left
side. Is 13 before and after that, before or
after that, and you just repeat that
process until you either find 13 or you
know that 13 can't be in it.
So how fast is this is algorithm? Well let's
imagine we start off with n elements so
we have a search space of n elements. In
a single comparison, just one, we've cut
our search space down to n over 2. Then
with one more comparison we cut it down
to n over 4 and then in half again and
half
and half and half again. So how many total
operations in the very worst case will
we have to run until we figure out if it
contains an element or not?
Well the total number of operations we'll
have to do is determined by how many
times can we divide n by 2 until we get
down to just one. So this is what log of
n expresses. A log base 2 of n
expresses. So if you pause the video you
can study that math for a second and see
the relationship between those two
things. But this means that binary search
is a log n problem. Let's look now at the
implementation of binary search. To
implement binary search we can either
implement it recursively or iteratively. 
We'll do recursive implementation first.
I'm gonna just copy and paste here some
just straightforward code for the
binary search call so this is a initial method that calls off to this
binary search recursive method with the
right parameters. So we're going to start
off initially with left being zero and
right being the very right point, so these
are inclusive endpoints. So first of all,
if things get kind of too big, if the left
winds up bigger than right, then we know
we have an error, we can't find it. And we
don't want to return true. Otherwise, we want to
pick the midpoint so left dot right divided by 2,
so that's going to be the midpoint. And if we found the
element, if array of mid is actually the
element we're looking for, then we should
return true. Otherwise if X is on the
left side of mid then go search the left
side. And as a pass an array X and left will
stay as is and the right point will
move to one next to the mid. Otherwise go
search the right side. So we want to call
very similar method but now the left point
moves up to mid +1 and right stays as is.
Ok so that's how the binary search
recursive implementation looks. So one
little minor pitfall is that, and some people
like to be careful of, is that left plus
right can actually overflow it with java
integers so if you'd like to avoid the
integer overflow issue you can actually
just do this instead and this will
prevent the overflow. It's kind of
up to you but this is one way of doing
it.
Ok so now that we've done the recursive
implementation let's turn to the
iterative implementation. So what I'm
going to do is I'm going to actually
tweak this recursive implementation, I'm going to
copy and paste it into a new function, and I'm going to
tweak it to make iterative. So I'm going
to call this iterative and I no longer
need parameters in here. But what I'm gonna
do is I'm going to set something to show
you how you can tweak it so I'm going to set left
to be that right is going to start off
at the rightmost position in the array.
So now I want to iterate, I
want to loop through this as long as
left and right are such, in the correct
positions. So change this to a while loop.
Alright. And then if I exit here that I
haven't found it
Ok so this looks correct and then here I
don't want to actually recurse anymore.
What I want to do is essentially take
these values here. So left is gonna stay
as is, and right is going to move to mid-
minus 1, I'll comment that out and I'll delete
it shortly, and then here rather than, so
left is going to stay or left is going
to become mid plus 1 and right is going
to stay as is. So that's how easy it is
to tweak it from recursive to iterative.
So that's how we implement binary search.
Remember that it can be implemented
recursively or iteratively, and it can
also be applied to other data like
strings or something else but it must
always operate on something that's
sorted. So now that you've seen the
implementation of binary search
why don't you try to do binary search on
a new data type like a string.
Good luck.
